パスワードを忘れた? アカウント作成
14178068 journal
日記

espyの日記: Elixir でプログラミング 3

日記 by espy

Elixir 初プログラミング。

  抵抗分圧回路

  Vin ───┐          
       □ R1        
       │          
       ├───→ Vout  
       │         
       □ R2       
       │         
        GND

  にて、 Vout = Vin * R2 / (R1+R2) なのであるが、 Vin, Vout を指定して、
  目的の Voutが得られる抵抗 R1,R2の組み合わせをE24系列から選定するプログラムを
  作った。

# volt_divider.exs --- search proper R1,R2 combination of voltage divider circuit
#
#  usage: elixir volt_divider.exs <Vin> <Vout>
#            Vin, Vout : float
#
 
e24 = [1.0, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2.0, 2.2, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.3, 4.7, 5.1, 5.6, 6.2, 6.8, 7.5, 8.2, 9.1]
e24resisters = e24 ++ (for x &lt;- e24, do: x*10)
 
vin = String.to_float(hd(System.argv))
vout = String.to_float(hd(tl(System.argv)))
 
result_sorted = (for r1 <- e24resisters, r2 <- e24resisters, do: [ abs(vout - vin * r2/(r1+r2)), vin * r2/(r1+r2), r1, r2 ] )
               |> Enum.sort
 
for j <- 0..4 do
  [ err, vout, r1, r2 ] = Enum.at(result_sorted, j)
  IO.write("R1 = ")
  IO.write(r1)
  IO.write(",\tR2 = ")
  IO.write(r2)
  IO.write(",\tVout = ")
  IO.write(vout)
  IO.write(",\terror = ")
  IO.puts(err)
end

実行例:

D:\Usr\Elixir>elixir volt_divider.exs  5.0 3.3
R1 = 4.7,       R2 = 9.1,       Vout = 3.2971014492753623,      error = 0.0028985507246375164
R1 = 47.0,      R2 = 91.0,      Vout = 3.2971014492753623,      error = 0.0028985507246375164
R1 = 6.2,       R2 = 12.0,      Vout = 3.296703296703297,       error = 0.003296703296702841
R1 = 2.0,       R2 = 3.9,       Vout = 3.3050847457627115,      error = 0.005084745762711673
R1 = 20.0,      R2 = 39.0,      Vout = 3.305084745762712,       error = 0.005084745762712117
 
D:\Usr\Elixir>

# スラド日記で使えるタグ一覧は今どこにある?? code, pre, blockquoteどれも
# 「<-」 がコメントの始まりになってしまう... 「&lt;-」 と手動で直すしかなかった..

# (5/7追記) コメント頂いた、ecodeタグでうまくいきました。

この議論は、espy (3615)によって ログインユーザだけとして作成されたが、今となっては 新たにコメントを付けることはできません。
  • 私も困っていたのですが,最終的には過去のスラド日記をググって見つけた https://srad.jp/comment/2079271 [srad.jp] を随時参照しています。

    <ecode>
    A -> B
    </ecode>

  • by Ryo.F (3896) on 2020年05月09日 13時15分 (#3811664) 日記

    私も駆け出しアルケミストですが。

    e24resisters = [1, 10] |> Enum.flat_map(fn k ->
      [1.0, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2.0, 2.2, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.3, 4.7, 5.1, 5.6, 6.2, 6.8, 7.5, 8.2, 9.1] |>
        Enum.map(fn r -> k*r end)
    end)
     
    [arg1, arg2|_] = System.argv
    vin = arg1 |> String.to_float
    vout = arg2 |> String.to_float
     
    result_sorted =
      e24resisters |>
      Enum.flat_map(
        fn r1 -> e24resisters |>
            Enum.map(fn r2 -> {abs(vout - vin * r2/(r1+r2)), vin * r2/(r1+r2), r1, r2} end)
        end
      ) |>
      Enum.sort
     
    result_sorted |> Enum.slice(0..4) |> Enum.each(fn {err, vout, r1, r2} ->
      IO.puts "R1 = #{r1},\tR2 = #{r2},\tVout = #{vout},\terror = #{err}"
    end)

    二重ループは、forの方がスッキリかな。
    四つ組{err, vout, r1, r2}を扱うとこは、リストでなくタプルが適切な気が。

typodupeerror

日々是ハック也 -- あるハードコアバイナリアン

読み込み中...