プログラミングのお題スレ Part9 [無断転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
>>786
問題勘違いしてました。素直にぐるぐる回すように修正しました。
https://paiza.io/projects/ncIY4LljeBahWZPJpd8ZPQ
下の「入力」タブの方にスペース区切りで b, c, d の値を1行づつ並べて入れてから実行させると「出力」に結果が出ます。
とりあえず >>768 に書いてある値を入力にセットしたところ出力は同じになりました。 >>787
入出力の確認をしただけですが、今回は問題ないようです
paiza使うと簡単に確認できて便利ですね >>768
僕の頭だとどうしても右端から左端に行くときの動きがイメージできないので、解答締め切ったあとでもいいのでちょろっと教えてもらえると嬉しいです
上3つまではわかるけどそこから先がそもそも答えにたどり着けない…… >>789
ヒント。
(インデックス++)%配列の長さ
を繰り返すとどうなりますか?%は余剰デス。 >>789
上の3つまでは分かるということなので、3つめのcの値を一つずつ増やしてみると、こんな感じになります
"7"、"78"、"789"、"7890"と並ぶ数値が増えていっているのが分かると思います
c+d の合計は9が最高なので、これ以上cを増やすにはdを減らさなくてはなりません
b = 7 c = 1 d = 5 a = 1273456890
b = 7 c = 2 d = 5 a = 2378456901
b = 7 c = 3 d = 5 a = 3478956012
b = 7 c = 4 d = 5 a = 4578906123
今度はcを2に固定して、dの値を一つずつ増やすと、こんな感じになります
"78"の並びが一つずつ右へずれていっているのが分かると思います
c+d の合計は9が最高なので、これ以上dを増やすにはcを減らさなくてはなりません
b = 7 c = 2 d = 1 a = 0123456978
b = 7 c = 2 d = 2 a = 8123456907
b = 7 c = 2 d = 3 a = 7823456901
b = 7 c = 2 d = 4 a = 2783456901
b = 7 c = 2 d = 5 a = 2378456901
b = 7 c = 2 d = 6 a = 2347856901
b = 7 c = 2 d = 7 a = 2345786901
こんな感じで分かるでしょうか?私も自分の頭で考えると混乱しますw 自分の考え方は、配列の一部を切り取ってパッディングするんだけど、
まず配列を回転させて切り取る第0インデックスを配列の最初に持って来る。
すると、配列の後ろにはすでにパディングが終わった数列のができてる。
で切り取って削除して尻尾にくっつける。
で、さっき回した分を戻してやると完成。
という方法で、>>770を解いた。 自分の考え方は、配列の一部を切り取ってパッディングするんだけど、
まず配列を回転させて切り取る第0インデックスを配列の最初に持って来る。
すると、配列の後ろにはすでにパディングが終わった数列のができてる。
で切り取って削除して尻尾にくっつける。
で、さっき回した分を戻してやると完成。
という方法で、>>770を解いた。 あちゃー
二重投稿になったある。
そんなに大事でもないのだけど。 C++は比較的不自由な言語なので頭使うのは鍛えられるよ。
パーツが少ないのでほとんど自作しないといけない。 コンパイルが必要とかでスクリプト系の言語より
使うことに不便があるかもしれないが、
できるアプリが自由で高速・軽量!
ライブラリもSTLやboost以外にも、探せば便利なのがいっぱい。 よそのライブラリ使うとイデオンで動かないからなぁ。
まぁ、業務ではライセンスに合ったものを使えばいいよ。 >>789
塊が移動すると考えれば良い。
例えば 7, 4, 2 だとすると、 789 と先頭の 0 が移動する塊だ。
で、ちょっと分かり易くするためにこの塊を伏せて * で書くとするとこうなる。
*123456***
それでこの塊を右に一つずらす。その時に1は食われて尻尾から吐き出される。
**234561**
移動量2なのでもう一回右にずらす。すると2が食われて尻尾から吐き出される。
***345612*
それでは * から 7890 に戻してみよう。
8903456127
できあがり。 >>793
これ間違ってるな。
最後尻尾にくっつけるんじゃなくて、適所にインサートだった。
で戻す。
書いた日から時間たってるからすまん。 >>790
>>791
>>798
ありがとうございます
やっと理解できました
がんばって解いてみます log2だけど、これ使うといいらしいよ。分割統治法のBSA法というやつらしい。
2個ずつの積を繰り返すことで計算回数が減らせる。
{{1, a0}, {0, r}}*{{1, a1}, {0, r}}を[ [○,P], [○,Q] ]とおくと
r*P/Qはa0 + a1/rであり、
{{1, a0}, {0, r}}*{{1, a1}, {0, r}}*{{1, a2}, {0, r}}を[ [○,P], [○,Q] ]とおくと
r*P/Qはa0 + a1/r + a2/r^2。
上の式を実際に計算してみる。
http://www.wolframalpha.com/input/?i=%7B%7B1,+a0%7D,+%7B0,+r%7D%7D*%7B%7B1,+a1%7D,+%7B0,+r%7D%7D*%7B%7B1,+a2%7D,+%7B0,+r%7D%7D >>801
普通のlog 2の計算には使えても
>>680 には使えないかと >>731 から更に縮まりました
もう誰も興味が無いかも知れませんが
コードいる? n=10^10で19.28秒にまで縮めた
n=10^13くらいまでなら夜寝てる間に終わる
>>804
期待してます! 804だけど考えてみたら面倒なんだな。
有理数(整数)で完全に求めてから割り算するのは時間かかりそうだから、
展開も、割り算も、有限で打ち切って求める精度がでるようにするのが普通? お題
辺の長さが10,000以下の整数である直方体について
すべての面の対角線も整数となるものを全て求める >>807
答えは浮かんだけど、
手元にインタプリタがないので書けない。 >>805 のソース一式とexeです。
>>680 の回答となります。
http://fast-uploader.com/file/7068204781334/
実行ファイルは、拡張子をexe_からexeに変えてください。
OSはWindows 64bit Vista以降
CPUはHaswell以降
で動作します。 作ってみたけど、オッセ―。
なんか数学的にやらないとダメぽ。
>>810
検索したら出てきた。
ただのHYPODだった。 あ〜ん。足し算10兆回かかるとかむりげーじゃ。
どうしようかこれ。 >>807
https://ideone.com/5Tu6fx
C++。ギブアップ。遅すぎだ。
デバッグ不完全だからそこを忘れないで。
多分1日かけても終わらないと思う。 >>807
特に大きな工夫もなく普通に3重ループで出来ましたよ
151個かな ぶ。おれは・・・いったい・・・。
だめだなぁ。才能ないなぁ。 >>801のように積へ変換した場合、どれ位の精度・桁数が必要なのか簡単にわからないな。
>>801でやると、誤差ありの巨大な数同士の掛け算になって、その結果誤差が拡大する。
和のままやると、適当に2ベキをかければ、各項の整数部分だけ計算すればよさそうだけど。
>>801は桁を十分にとったとしても、2進10桁以上の部分も計算途中で無視はできないか。 グア。題意勘違いしてた。
直方体の対角線はいらんのか。うおー。
ばかばかー。 >>807
https://ideone.com/Uipgvw
C++。書き直したら、>>816のパクリ見たくなった。
そしてそれでも遅いとかあかんなー。
うーん。なんでなんだろう・・・。 >>820
普通に、求めたい精度+α の精度を保てば十分かと
演算回数はlog(n)のオーダーなので
普通にlog(2)を求める時には使える手法 物体は表面だけでなく無数の内面を有するという考えは絶対に存在する
一方で全てを表面でしかとらえない人の存在も否定できない log2は>>801でもできそうだ。
積の先頭ほど精度が必要で、無視できる上限・下限を積の位置で可変にするか、
最初の積の計算で必要な精度をすべてに適用するかでいけそう。 >>817
これパクってstd::bitset<10001>でやったら動かないかな
nextSetBitだけ作れば動きそう >>807
これでいいかな?
Kotlin で書いた。しかしpaiza.ioの制限なのか、何故か import kotlin.math.* がエラーだったので java.lang.Math の関数を使っている。
https://paiza.io/projects/ImbYdf3NSWgW-zj8Ke6cDw >>833 ruby
i,j=0,-1;p i while(i+=j+=1)<10000 >>833 Brainf**k ワンライナー(笑)
https://ideone.com/TyMeco
遅すぎて8bitまでしか計算できなかった ideone.comはたいして最適化しないBrainf**k処理系だからな >>833
1+2+3+... だよね? じゃあこうだ。
perl -e '$i=0;$n=1;while(($i+=$n)<=10000){print"$i\n";++$n}' >>833
while じゃなくて for にするとこう。
perl -e 'for($i=0,$n=1;($i+=$n)<=10000;++$n){print"$i\n"}' >833 R
cat(cumsum(0:140)) >>801は精度管理の手間を考えたら、そのまま級数計算するのと大差ないと諦めたが。
こうすれば割り算の小数計算がほぼでないからいいのでは? 既に実装済?
an = 1/n、r = 2として、Σ an/r^n を定数C倍したやつの整数部分の取り出し。
C*anを再びanとおく。
Σ an/r^n
= a2/r^2 + a4/r^4 +・・・+ aN(2)/r^N(2) (添え字は2の倍数を動く)
+ a3/r^3 + a9/r^9 + a15/r^15 + ・・・+ aN(3)/r^N(3)
+ ap/r^p + ・・・+ aq/r^q + ・・・ (pは素数、qはp未満の数で割り切れないpの倍数)
= 1/N(2)r^N(2) * ( N(2)*a2*r^(N(2)-2) + ・・・ + N(2)*aN(2) ) + ・・
この分子部分は、各項、整数でそのまま計算しても>>801でも速くなるはず。 秒数ではCPU依存するから正確に比較できない。
掛ける2だけのループを10^10回するだけでも19秒では終わらない。
無料のideone codepadなどの実行可能時間以内にできる範囲とか、
ベースとなる簡単なコード、関数の何倍時間がかかるかなどだと比較できるけど。 くだらん話かも知れんけど
竹内関数のメモ化
https://ideone.com/sVhke1
これはC++によるものだけど、C++や他の言語でもっと高速に書く方法はあるか? あ、ちなみにideoneの結果は間違っている
多分スタックオーバーフローしている
100, 50, 0の場合は答えは100 >>849
constexprにすれば実行時はほぼ計算無しにできると思う。
コンパイル時間半端ないけど。 ところで、いくらメモ化してても5回しか呼ばれないってことがあるのか?って気はする。 https://ideone.com/Y9WhRz
竹内関数constexprにしてみた。
ウチの環境だとこの辺のパラメータが限界っぽいかな。
100,50,0だとメモリ使い切るらしい。 あら、コンパイルエラーになっちゃった。
VCだと通ったんだけど。もちろんステップ数とか設定はいじってるが。 お題
6つの辺の長さが 与えられた4面体の体積を求める お題
8つの辺の長さが与えられた超5面体の体積を求める お題
与えられた自然数を高々四個の四角数(平方数)の和で表せ >>856 Ruby
https://ideone.com/qbHExm
ただし四面体ABC-Dに対して入力の順序は
AB BC CA CD DA BD とする >>857
8つだと多胞体が一意に定まらないと思うんだが >>853
64bit環境でやったらスラッシング起きて\(^o^)/ >>862
10でも足りないと思うんだけどひょっとして超五面体って五胞体のつもりで言ってる? >>861
ウチはi6700メモリ8Gだな。20秒くらいボケーっとしてたらコンパイル完了する。
実実行より全然早い。 >>866
んー32bitでコンパイルしてみるかな
64bitはマジ卍ヤバい >>866
悪い
VCで /constexpr:steps 1000000を付けてコンパイルしたら4秒ほどでコンパイルが終わった
多分/MPも付けてるからだと思う
実行結果は25になった
gcc 7.2.0 64bitだとどんどんメモリを食って行って最後にスラッシングが起きる
馬鹿正直な実装をしているからかも知れないね
VCの方がいろいろとメモリを食わないように工夫されてるのかも
Clangでも/constexpr:steps は -fconstexpr-steps という形でサポートされてるようだから
多分行けると思う
メモリ64G積んでるし >>868
いいマシーンだな。
まぁ、ウチはあれくらいで資源尽きちゃうけど、メモリ64Gもあったらもっと行けるな。
気が向いたらどうぞ。 以下のURLのように、同じ色の点同士をつなぐゲームがある。
https://play.google.com/store/apps/details?id=com.bigduckgames.flow
N×Mの2次元配列が与えられる。配列の各要素は半角英字('a'-'z')または'*'である。
半角英字は色付きの点を表し、'*'は空のマスを表す。
'*'以外の文字は、配列中に必ず2個ずつ存在する。
このパズルの解を一つ出力せよ。
・'-'は左右のマスをつなぐ
・'|'は上下のマスをつなぐ
・'.'はマスをつながない
解がない場合は"No solution"と出力せよ。
[input]
***rg
**bg*
r****
ob*yo
****y
[output]
*-*-*-r.g
|.......|
*.*-b.g-*
|.|......
r.*.*-*-*
..|.|...|
o.b.*.y.o
|...|.|..
*-*-*.*-y >>841
やってはないけど、そもそもこれ間違ってるのと、同じような発想でやるとしても
全ての素数での分類ではなく、3分割くらいのほうが効率がいいのと、
Σ (2の倍数) + Σ (3の倍数かつ2の倍数でない) + Σ (2と3で割り切れない)
分割する事もなく、N項の和だとしたらNの階乗か分数をなくせる最小公倍数かけてもいい。それだと掛け算もしくは割り算がいくつも出てくるが。 >>871
等幅フォントで表示しているエディタにコピペしてようやっと何を言わんとしているか分かった。
それってマスとマスの間に - または | を入れて繋ぐってことでいいんだよね? で、つながない所がピリオドだと。
(まあ等幅フォントのASCIIでやるならそれしか方法ないとは思うけど)。 しかしピリオドは
**
**
の時に
*.*
...
*.*
のようになって中央のピリオドが本来なら不要なものになるわけだが、それはスペースでなくても良いのかな?
まあただの幅合わせだからどうでもいいものではあるが。 >>801 の方法で出来ると書いてるけど
結局誰もやってないのか
個人的には(高速には)出来ないと思っている >>871
課題じゃなくて
単にソルバーの作成依頼でしょ 無理に線引かないでrだのgだので埋めた方がわかりやすいと思うがな
すべてのマスを埋めなければならないルールが抜け落ちてるみたいだから
実は別物のゲームで交差があるとかなったらそうはいかないが ブレゼンハム的なやつって、始点と傾き(と区間や境界等で決まる明示されない終点)が
与えられた際に、終点座標を求めてから始点に向かうのってアリなんだろうか? ここでやるには問題がでかすぎ
100分割してほしい 訂正
ただし解は1つでありかつ線が通らないマスは無いことを前提とする
ではなく
解が存在すればすべての解は全てのマスを通ることを前提とする お題
22の分割(たとえば3+3+5+8)のうち
分割したそれぞれの数の逆数の和が1になるものを求める 早速間違えましたすみません
3 +5 +6 +8
でした >>883 ruby
f=->n,k{n==1?[[k]]:(1..k/n).flat_map{|i|f[n-1,k-i].map{|j|[i,*j].sort}}.uniq}
(1..22).each{|i|f[i,22].each{|a|p a if a.map{|e|1r/e}.sum==1}}
#=>[2, 4, 8, 8]
[2, 5, 5, 10]
[3, 3, 4, 12] C++で書いたけど、オセー。
デバッグ大変だ。
うーん。困ったなぁ。 ■ このスレッドは過去ログ倉庫に格納されています