プログラミングのお題スレ Part19
■ このスレッドは過去ログ倉庫に格納されています
>>163 octave https://ideone.com/GX9hjP f = @() rand(randi([4 20]), 1); >>196 haskell import Data.List c = id . map length . map (\x -> takeWhile ( <= ( last x ) ) . reverse $ x) . tail . inits main = do print $ c [ 3, 1, 2, 6, 6 ] ---- [1,1,2,4,5] >>143 Kotlin >>194 のJavaのやつを見て>>158 のKotlinのやつを改造した。 https://paiza.io/projects/iNRMUv2Annc6YFqJjAO4wg 要するに >>158 を作っている時に String#codePoints() に気付いていなくて自作してしまったということだが、 Java 8 から追加されたメソッドのようなので、>>158 は古い JVM ライブラリでも動くということではある。 お題 >>196 を小学生にも理解できるぐらいのやさしい日本語に翻訳せよ。 このスレの住人なら日本語分からなくても例だけ見れば普通に理解できるだろ IQテストみたいなもんだ >>206 こういう事じゃない? 入力値が遡って比較する最大個数と値を兼ねてるんでしょ 同値ならindex(1始まり)の大きい方 入力:3 1 2 6 6 4 3 [(3)] →1 1 [3 (1)] →1 2 [3 (1 2)] →2 6 [(3 1 2 6)] →4 6 [(3 1 2 6 6)] →5 4 [3 1 (2 6 6 4)] →3 >>209 最後の4違うぞ 入力:3 1 2 6 6 4 3 [(3)] →1 1 [3 (1)] →1 2 [3 (1 2)] →2 6 [(3 1 2 6)] →4 6 [(3 1 2 6 6)] →5 4 [3 1 2 6 6 (4)] →1 x_iは要素数。上の例でいうと()の中の数が何個あるかってこと。で、(右から)直近の要素の中での最大値が一番右の数字になるのは最大でいくつかってこと。 一番下の4のケースでは次の6を含んでしまうとMAXが4にはならないので要素数1で打ち止め。 現在地から前に遡って見ていって自分と同じか小さい要素が続く数を 最初から最後まで求めるだけ もっと早く一発で求める方法があるかは分からないけど >>206 長さ N の整数列 A が与えられる A の連続した部分列であって、各 i (1≦i≦N) について次の条件を満たすものをすべて求めなさい ・整数 j (1≦j≦i) を max(A_j, A_{j+1}, ..., A_i) = A_i を満たす最小の j とし i - j + 1 の値 >>196 C++ O(N log N) セグメント木を使うと区間 max の二分探索を O(log N) で行える atcoder の aclib を使用 https://wandbox.org/permlink/8rm8MsauDMJhvpAf お題 将棋のルールで可能な最初の2手を全て求める。 なるほど (∞,0)のみからなるリストから始めて(-値、インデックス)についての辞書式順序(ただしインデックスは降順)でリストに追加していくと考えればいいのか i番目の要素(v,i)が来た時(u,h)<(w,j)の間に入るならvより大きい最大のインデックスはjだからi番目の出力はi-jになるのか >>216 先手後手ともに可能性が30通りあるのでそれらを単純に組み合わせて出力すれば良い 最初の初期状態の配置ならつまらんね 途中経過のどの状態からでもすべての2手(3手でもいいよ!)を出力とかなら 本格的な将棋プログラム組まないと導き出せない お題:sortしてreverseしてforeachせよ https://ideone.com/35HTkC List(7, 8, 3, 6, 4).sorted.reverse.foreach(print) >>224 rust https://ideone.com/SY2DMY fn main() { let mut v = [7, 8, 3, 6, 4]; v.sort(); v.reverse(); v.iter().for_each(|x| println!("{}", x)); } >>224 dart https://ideone.com/w26D8S void main() { var a = [7, 8, 3, 6, 4]; a.sort(); a.reversed.forEach(print); } >>224 ocaml https://ideone.com/bitFC6 List.iter print_int (List.rev (List.sort Pervasives.compare [7; 8; 3; 6; 4])) >>224 ruby https://ideone.com/K14REi [7, 8, 3, 6, 4].sort.reverse.each(&method(:p)) >>224 octave https://ideone.com/E2DoUr arrayfun(@disp, flip(sort([7 8 3 6 4]))) >>224 C++ for (auto i : multiset<int, greater<int>>({ 7, 8, 3, 6, 4 })) cout << i << endl; >>224 Perl5 print reverse sort qw(7 8 3 6 4); 実行結果 $ perl 19_224.pl 87643 >>224 Perl5、foreach も要るんやったね… print foreach reverse sort qw(7 8 3 6 4); 実行結果 $ perl 19_224.pl 87643 >>224 Bash cat <<EOS | sort -r | while read v; do echo ${v}; done 7 8 3 6 4 EOS >>224 Ruby [7, 8, 3, 6, 4].sort_by(&:-@).each{p _1} >>229 > print foreach reverse sort perlってこんな気持ちいい書き方できる言語やったんけ 正直恐れ入った お題: 俺のチ〇コの長さ分だけfor文でカウントしてカウント変数を出力せよ >>232 perl for ($i = 0; $i < 1; $i += 0.1) { print "$i\n" } お題: 日付をYYYYMMDD形式で表したとき、それを表す整数が今日より後に素数になる日付を求めなさい。 >>224 Kotlin script kotlinc コマンドで REPL にして直接入力して実行した時のコピー。(>>> はプロンプト) 出力は println() を使って1つづつ改行させた。 >>> listOf(7, 8, 3, 6, 4).sorted().reversed().forEach { println(it) } 8 7 6 4 3 >>> お題: 整数 N が与えられます 長さ N の正整数列 A_1, ..., A_N であって以下の条件を満たす lcm(A_1, ..., A_N) が最小のものを求めなさい ・gcd(A_1, A_2) * gcd(A_2, A_3) * ... * gcd(A_{N-1}, A_N) * gcd(A_N, A_1) = lcm(A_1, ..., A_N) 制約: 3≦N≦4000 例: 入力: 5 出力: 6 15 35 77 22 >>238 perl print join ' ', (1) x $ARGV[0]; Aiの制約で.... Aiが異なる正整数なら N=5 [1,2,4,8,64] ->lcm=64 Ai>=3 なら N=5 [5,7,14,6,15] -> lcm=210(=1*2*3*5*7) (同じlcmで数列は複数作れる) ※あの例はどういう条件だろう すいません... 素数を小さい順に組み合わせて 2*3, 3*5, 5*7, 7*11, 11*2 とすると綺麗に数列が作れていいなーと思って投稿したのですが、最小ではなかったようです... このお題は無かったことに お題、灘中入試っぽい問題 開始点S から、終点G まで、最短距離9 で移動する方法は、何通りあるか? 移動は右か下へ、1ずつ移動できるが、* は通れない所である。 数字は通れる所で、単に分かりやすくするために座標を書いただけで、移動コストではない S23456 12*456 1234*6 123456 12345G プログラムなら実際に駒動かしてかぞえるの? なんか、足し算引き算で出来そうだよね、 >>248 sh echo 48 #やっぱ計算しなきゃダメ? お姉さん問題なら、 Ruby で、そのライブラリを使って解いてみて 超高速グラフ列挙アルゴリズム 〈フカシギの数え方〉おねえさん問題 BDD/ZDD の湊真一が、北大から京大大学院の教授へと出世してる https://ideone.com/b2CQ5a 48ってなったからあってるのかな適当に作ったけど お題: これ出題してみるか。 黒板に1〜nの自然数が一つずつ書かれている。 二人でかわりばんこに次のルールで黒板に書かれた自然数を消していくゲームをする: ・自分の番のとき、黒板に残っている数から一つ選び、 その数及びその数の約数をすべて消す。 ・自分の番で黒板の数をすべて消し去ったとき勝者となる。 実はこのゲームはnによらず先攻必勝であるが、初手をどう打つかを判断するのは簡単でない。 1〜30のすべての自然数nについて、後攻を勝たせないために初手で先攻が選ぶことができる数をプログラム中で5秒以内に計算し、すべて列挙せよ。 1〜30ならデータベース化してしまえばなんとかなるな >>248 9C4 - 3C1 * 6C3 - 6C2 * 3C1 + 3C1 * 3C1 * 3C1 = 48 >>248 お受験風にdpで数え上げる Haskell test1 = "" ++ "┏┳━┳┳┓\n" ++ "┣┫ ┣┻┫\n" ++ "┣╋┳┫ ┃\n" ++ "┣╋╋╋┳┫\n" ++ "┗┻┻┻┻┛\n" to01 = let parseC c = if c == '\x2001' then 0 else 1 parseL = map ( parseC ) in map parseL . lines cntRoots posCrs = let z y x = zipWith ( * ) y $ zipWith ( + ) x $ ( 0 : ) $ z y x rs = id $ ( ( 1 : ( repeat 0 ) ) : ) $ zipWith z posCrs rs in rs nRoots = last . last . cntRoots main = print $ nRoots $ to01 test1 ---- 48 >>248 再帰で全パターンやらせるようなのは誰もがやりそうなので他の人に任せるとして、後はやるとしたらスレッド使ってやるぐらいかねえ。再帰は再帰だけど、うまくいけば速く動きそう。(スレッド作るコストが高くて遅くなるかも知れんが)。 ま、しかし、今は麻婆豆腐定食食ってる最中なのでできない。後で時間が空いた時にまだ覚えてたら作ろう。 総当たりから、* で通る経路を引くぐらいしか、思いつかない >>260 漏れも、そういう木を考えた ちなみに>>260 はお受験で出てくる 1 1 1 1 1 1 1 2 x 1 2 3 1 3 3 4 x 3 1 4 7 11 11 14 1 5 2 23 34 48 と上から順に数える方法です Haskellのdpは読みにくい オレの書き方が下手なだけか?orz 開始点から数え上げるので良かったのか 漏れは、終点から数え上げる方法を考えていた お題:以下のパイプを実現するプログラムprogを作りなさい $ echo "1 + a" | prog 1a $ echo "b + 3" | prog 3b $ echo "2 + d + 1 + c" | prog 12cd >>267 Kotlin https://ideone.com/6Il455 いやー。スマホで入力するのは大変だな。画面は小さいはエディタはまともにうごかんはで非常に疲れた。 >>267 Ruby $ echo "1 + a" | ruby -e"$><<gets.scan(/\w+/).sort.join" 1a $ echo "b + 3" | ruby -e"$><<gets.scan(/\w+/).sort.join" 3b $ echo "2 + d + 1 + c" | ruby -e"$><<gets.scan(/\w+/).sort.join" 12cd >>267 echo "1 + a" | perl -pe 's/[ +]+/\n/g'|sort|perl -pe 's/\n//' 1a echo "b + 3" | perl -pe 's/[ +]+/\n/g'|sort|perl -pe 's/\n//' 3b echo "2 + d + 1 + c" | perl -pe 's/[ +]+/\n/g'|sort|perl -pe 's/\n//' 12cd >>267 $ echo "2 + d + 1 + c" | sed "s/ *+ */\n/g" | sort | xargs | sed "s/ //g" 12cd >>266 答えも解き方もあってるとおもう 総当たり以外の方法で解けないかなと思ってるところだけど 先手必勝が分かってるのに具体的な勝つ手は簡単に分からないもんなの? >>275 必勝手を簡単に導くアルゴリズムが、どこかにあるといいなと思います ただ、そのアルゴリズムがわからなくても先手必勝は証明できます 必勝手を指すのと必勝パターン数を計算するのはまた別物だしな お題: H×Wのマス目が与えられます。 始点'S'、終点'G'、通路'.'、壁'#'であり、壁や範囲外のマスは通ることができません。 また、始点と終点は隣り合っていないものとします。 いくつかの通路を壁に変更して、始点から終点に到達できなくするには 最小でいくつ壁が必要でしょうか? [入力] H W (マス目を表す文字列) [入出力例] 1 5 S...G => 1 3 3 S#. #.. ..G => 0 4 4 .... .S.. ..G. .... => 4 お題:ニセコインを見つけよ 半年毎に数学板で出てくるお題 n枚のコイン(n≧3)の中から重さの違うニセコインを見つけには何回天秤つかえばよいか なおどのコインも最低一回は天秤に乗せてニセコインが重いか軽いかも判定するものとする 答えは e = ceiling( logBase 3 ( 2*n+2 ) ) さてさてこの回数で可能はそんなに難しくない 実際e行n列の1,0,-1からなる配列で @どの行も1の数と-1の数が等しい(右の皿と左の皿に同じ数乗せる) Aどの相異なる行u,vをとってもu ≠ ±v となる配列が作れる そこで n≧3 にたいしてこのような配列を出力するプログラムを作って下さい 例 3-> [[-1,0,1],[0,1,-1]] 10-> [[-1,0,1,-1,0,-1,1,1,-1,1],[0,1,-1,-1,0,0,0,-1,1,1],[0,0,0,0,-1,1,1,-1,-1,1]] 12-> [[-1,0,1,-1,0,-1,1,1,-1,0,0,1],[0,1,-1,-1,0,0,0,-1,1,-1,1,1],[0,0,0,0,-1,1,1,-1,-1,1,1,-1] 39-> [[-1,0,1,-1,0,-1,1,1,-1,0,0,-1,1,0,1,-1,-1,1,0,0,1,-1,-1,1,0,0,1,-1,-1,1,0,0,1,-1,-1,1,0,0,1],[0,1,-1,-1,0,0,0,-1,1,-1,1,-1,1,0,0,0,1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,0,0,0,0,0,0,1,-1,1,-1,1],[0,0,0,0,-1,1,1,-1,-1,1,1,-1,-1,0,0,0,0,0,0,0,0,0,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1]] 訂正 × Aどの相異なる行u,vをとってもu ≠ ±v ◯ Aどの相異なる列u,vをとってもu ≠ ±v >>279 最初しか読んでないが、その条件では軽い方が偽物なのか重い方が偽物なのか決定することが不可能 >>282 今確かめてみたら合ってるようです main = print $ [ ( n, ceiling $ logBase 3 $ fromInteger $ 2*n +2) | n<- [3..16] ++ [38..42]] [(3,2),(4,3),(5,3),(6,3),(7,3),(8,3),(9,3),(10,3),(11,3),(12,3),(13,4),(14,4),(15,4),(16,4),(38,4),(39,4),(40,5),(41,5),(42,5)] ちなみに軽重が確定しない=一度も乗せないのもありにすれば13枚でも3回で可能です 12回のときの解に「一度も乗せないコイン」を入れればいいだけなので ちなみにn=12とn=39のときの解でそれぞれ3回、4回で可能 [[1,0,1,-1,0,1,-1,0,0,1,-1,-1],[0,1,-1,-1,0,0,0,1,-1,1,-1,1],[0,0,0,0,1,-1,-1,1,1,-1,-1,1]] [[1,0,1,-1,0,1,-1,0,0,1,-1,1,-1,0,1,-1,-1,1,0,0,1,-1,-1,1,0,0,-1,1,0,0,1,-1,-1,1,0,0,1,-1,-1],[0,1,-1,-1,0,0,0,1,-1,1,-1,-1,1,0,0,0,1,-1,1,-1,1,-1,-1,1,-1,1,0,0,0,0,0,0,1,-1,1,-1,1,-1,1],[0,0,0,0,1,-1,-1,1,1,-1,-1,1,1,0,0,0,0,0,0,0,0,0,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1],[0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1]] >>279 ちょっと盛り上がらないのでアルゴリズムの一例例示してみます まぁここはプログラミングのスレだから数学部分はどうでもいいでしょう 構成法はほかにもいくつかあります なお{1,0,-1}はうるさいので{1,0,2}にします --- 以下において{ }で囲まれた数は3進数表示とする 以下3進数表示した時 最高位が1でそれ以外が0であるものを10型、 最高位が2でそれ以外が0であるものを20型、 最高位が2で次に来る0でない数も1であるものを11型 ‥ と定めていき、自然数全体を10型、20型、11型、12型、21型、22型と6型に分類する 与えられた自然数のうち @何もしない A最高位のみ1⇔2の交換をする B最高位以外1⇔2の交換をする C全桁1⇔2の交換をする で11型の変換できる 例えば{2201}=73であればCを適用して f11(73)={1102}=38となる 同様にしてf12,f21,f22を定義しておく では自然数eと3≦n≦(3^e-3)/2を満たす自然数nについて条件を満たす組みを構成する まずn-eが奇数のときn-a-1をm、そうでないときはn-eをmとおく 前者のときケースA、後者のときケースBと呼ぶ 次にe桁以下の11型の数からケースAでは{111‥11}(e桁)を取り除いたものを、ケースBでは{111‥10}(e桁)を取り除いたものを並べたものを考える (続く) (続き) この列の最初のm/2個を2個ずつ並べてm個にした列 {11},{11},{101},{101},{110},{101},{111}‥ にf11,f12,r21,f22を順に作用させていく ただし桁が上がるごとにf11に戻す 最初の方を例示すれば11型の数を2個ずつ並べたものが {11},{11} {101},{101},{110},{110},{111},{111},{112},{112}, {1001},{1001},{1010},{1010},{1011},{1011},‥ だから {11},{12} {101},{102},{210},{220},{111},{122},{212},{221}, {1001},{1002},{2010},{2020},{1011},{1022},‥ となる この列は偶数番目のどこで切っても各桁に現れる1の個数と2の個数は同数か1の方が2個多い事に注意する また最低位では常に1の個数と2の個数は同数になる よってケースAではe個の10型、もしくは20型の数を追加する事によって全てのくらいで1の個数がちょうど一個多くなるようにできる またこの時列の長さはm+e=n-1個である 最後に{222‥22}を追加して条件を満たす列ができる また同じくケースBではe-1個の10型、20型の数を追加して最低位だけ同数でそれ以外の桁では1の個数がちょうど一個多くなるようにできる この時の列の長さはm+e-1=n-1個である 最後に{222‥20}を追加すれば良い 盛り上がりませんね 解答例 https://ideone.com/cHEv2n 見栄え考えて"+ -"の三文字で表現してます まぁ数学というわけでもないです ただ数学板にはもう半年に一回くらい上がってくる 意外にネットでちゃんと解説してるサイトがない お題 整数 a_i が n_i 個ある。(1 <= i <= K) このデータの中央値を求めよ。 [入力] K a_1 n_1 ... a_K n_K [入出力例] 3 1 2 2 2 3 4 => 2.5 {1, 1, 2, 2, 3, 3, 3, 3}の中央値は(2+3)/2=2.5 2 0 1000000000 1 999999999 => 0 こわれてる K=3 i=4 K=3<4=i と i<=Kが矛盾 お題:機械翻訳しなさい 入力:this is a pen 出力:これはペンです 入力:is this a pen? 出力:これはペンですか? >>295 間違ってね? 3 1 2 3 4 2 2 とか 中央値は出現順の中央の値じゃないよ値の順の中央の値だよ 1,2,3,100 の場合 中央値は 2.5 ですか? それとも 2 または 3 ですか? ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる