プログラミングのお題スレ Part18
■ このスレッドは過去ログ倉庫に格納されています
入力と出力をはっきりさせてほしい それとも取引所の仕様を理解しろって話なの? 入力が任意文字列で出力がそれを含む有効なビットコインアドレス 例にあるやつだとMayukoMuraokaが任意文字列の部分 XXX…っていうのはただの本体データ160bitのあまりスペースを埋めてるだけだからなんでもいい それに対応して最後のチェックサムも任意性がある 直感だとブルートフォースが必要そうだけど実際は単純なやり方でできる 秘密鍵でデコードできなくてもいんでしょ? じゃあbase58で表されたバイト値と文字列を変換するだけじゃん 基本的にはそれだけのこと 実際の手順を考えるとちょっとややこしいことがあるくらい ということで実装してみよう >>366 全然おもんないやんけ もう一回チャンスをやろう お題: 二人の煽り耐性から「死ね」と言い合うプログラム 煽り耐性 0.1〜1 死ねと言い返す確率 (1-煽り耐性) * 100% 最初に死ねと言うのはA 入力 {Aの煽り耐性} {Bの煽り耐性} 例 > 0.1 0.8 A「死ね」 B「死ね」 A「死ね」 if (>>373 {A}%3 ==0.1&&0.8<<373{B}) print "オモロー" & "アキラ" *100% ; >>350 js const input = "programmingodaisure" let tmp_str = input; let tmp_hex = new Uint8Array(); do { tmp_str += "X"; tmp_hex = [0x00, ...Base58.decode(tmp_str)]; } while (tmp_hex.length < 25) const prefix_and_data = tmp_hex.slice(0, -4); const doubleSha256 = sha256.digest(sha256.digest(prefix_and_data)) const checkSum = doubleSha256.slice(0, 4); const result_hex = new Uint8Array([...prefix_and_data, ...checkSum]); const result_str = Base58.encode(result_hex); console.log(result_str); → "1programmingodaisureXXXXXXXZHx9sj" https://chainflyer.bitflyer.jp/Address/1programmingodaisureXXXXXXXZHx9sj BASE58とSHA256のライブラリ https://cdn.jsdelivr.net/npm/base-58@0.0.1/Base58.min.js https://cdn.jsdelivr.net/npm/js-sha256@0.9.0/src/sha256.min.js 「生」の読みはたくさんあるのに、 「死」の読みはひとつだけ。 示唆に富んでいる。 >>249 Elixir # 蓄積変数 set は、すべての文字列の集合。abcde, bcdea などの5つ。 # word は、1文字ずらした文字列 src_word = 'abcde' %{ set: set } = Enum.reduce_while( 1..length( src_word ), %{ set: MapSet.new, word: src_word }, fn _count, acc -> [ head | tail ] = acc.word next_word = tail ++ [ head ] # 1文字ずらす acc = %{ acc | word: next_word } if MapSet.member?( acc.set, next_word ) do { :halt, acc } # 既に存在すれば、break else acc = %{ acc | set: MapSet.put( acc.set, next_word ) } { :cont, acc } # ループを続ける end end ) # IO.inspect set # 文字列が、集合の中に含まれているか? [ 'deabc', 'cdeba' ] |> Enum.map( fn str -> MapSet.member?( set, str ) end ) |> IO.inspect # [true, false] お題: 縦H、横Wの迷路が与えられます。 スタートからゴールに至る道順の個数を求めてください。 迷路は通路から通路へ、上下左右の4方向へのみ移動できます。 ただし、一度通った通路を引き返すような道順は無効です。 また、スタートとゴールは通路です。 1行目に迷路の高さと幅を表す整数H、Wが与えられます。 2行目からH行にわたって、迷路を表す長さWの文字列が与えられます。 文字列は 'S' 'G' '.' '#' の文字のみからなり、それぞれスタート、ゴール、通路、壁です。 例1: 入力: 5 5 S.... ##.#. ...#. ##.#. ....G 出力: 2 例2: 入力: 5 5 S.... ##.#. ...#. ...#. ....G 出力: 12 お題: ロシアンルーレット。 リボルバーを回しますか? (Y/n) Y 1回目: 不発 リボルバーを回しますか? (Y/n) Y 2回目: 不発 リボルバーを回しますか? (Y/n) n 3回目: バーン! >>383-384 こんな感じか? 最初にリボルバーを回します。 (弾丸の位置を設定) こめかみor天井?(K/t) K 1回目: 不発 もう一度リボルバーを回しますか? (Y/n) Y (弾丸を回転) こめかみor天井?(K/t) K 2回目: 不発 もう一度リボルバーを回しますか? (Y/n) n こめかみor天井?(K/t) K 3回目: バーン! あなたの負けです。 銃の弾数と空砲/実包の割合とか オートマとリボルバーどっちかとか特定してからにしてくれ >>383 https://repl.it/@vip0/bullet#index.js // 0-5 const rand6 = () => Math.floor(Math.random() * 6); const gun = (() => { let pos = 0; const shuffle = () => (pos = rand6()); shuffle(); const shut = () => pos-- === -1 return { shuffle, pos, shut } })() // mock 1/2 rand const readDoShuffleAsync = () => { const y = Math.random() >= 0.5 console.log(y ? "y" : "n") return y } let i = 1; while (true) { console.log("リボルバーを回しますか?"); if (readDoShuffleAsync()) gun.shuffle() const bomb = gun.shut(); console.log(`${i}回目: ${bomb ? "バーン!" : "不発"}`); i++; if (bomb) break } VSCode の拡張機能、Quokka.js を使えば? 変数を書くだけで、内容が表示される var a = 1 a // 1 と表示される swift playgroundとかjestのinlineSnapshotみたいな感じか 使うときがあるか微妙 お題 nを受け取って1からnまでインクリメントされた配列を返してください インクリメントするごとに値の数だけ配列に値を追加してください 例 入力: 1 出力: [1] 入力: 3 出力: [1, 2, 2, 3, 3, 3] お題 配列をソートする関数を受け取って安定ソートか否かを判定する プログラムを作成してください お題: splitを実装せよ(ただし組み込みやライブラリのsplitは使ってはならない) 例: >> split('abc:def:ghi', ':') >> ['abc', 'def', 'ghi'] >>393 J f =: #~ @: >: @ i. >>393 Ruby (0..3).each{|n| p (1..n).reduce([]){|s, a| s + [a] * a}} # => [] [1] [1, 2, 2] [1, 2, 2, 3, 3, 3] >>395 Ruby p 'abc:def:ghi'.scan(/[^:]+/) # => ["abc", "def", "ghi"] >>393 octave https://ideone.com/wQ0EMk f = @(n) repelem(1:n, 1:n); f(3) >>395 JS let minSplit = (string, separator) => { let array = []; let splitter = (st, sp) => { let pos = st.indexOf(sp); if (pos == -1) {return [st,void(0)]} else {return [st.slice(0,pos),st.slice(pos+1)]} } while (true) { if (string.length == 0) {array.push(string); break} let temp = splitter(string, separator) if (temp[1] == void(0)) {array.push(temp[0]); break} else {array.push(temp[0]); string = temp[1]} } return array } let minSplit2 = (string, separator) => { let reg = new RegExp(`[^(${separator})]+${separator}?`, "g"); return `${string} `.match(reg).map(x=>x.slice(0,-1)) } >>395 octave f = @(s, d) arrayfun(@(b, e) {s(b:e)}, [1 find(s == d) + 1], [find(s == d) - 1 numel(s)]); f('abc:def:ghi', ':') >>395 js const replaceAll = (s, from, to) => s.replace(new RegExp(from, "g"), to) const split = (str, sep) => JSON.parse(`["${replaceAll(str, sep, '","')}"]`) split('abc:def:ghi', ':') // [ 'abc', 'def', 'ghi' ] ずるいしダブルクォート対応できてないけど思いつき >>395 Ruby # セパレーターの仕様が文字か文字列か分からなかったので文字列にした def split( str, sep ) res = [] (str + sep).scan( /(.*?)#{Regexp.escape(sep)}/ ){ res << $1 } res end split('abc:def:ghi', ':') #=> ["abc", "def", "ghi"] operator[]がconstexprなのはC++17以降らしいね >>393 Ruby def f(n) (1..n).map{|v| [v]*v}.flatten end お題: 覆面算パズルをランダムに自動生成せよ。 単語は大文字のアルファベットのみとする。 各単語は自然数を表している。 単語の各文字は数字を表している。 各単語の先頭はゼロではない。 同じ文字は同じ数字が入る。文字が違えば、数字も違う。 各単語は、3文字以上6文字以下とする。 答えは一つでなければいけない。 今回は、簡単な足し算のみとする。 例) SEND+MORE=MONEY. BASE+BALL=GAMES. 単語リスト:https://gist.github.com/deekayen/4148741 お題:覆面算パズルを解くプログラム。 例) SEND+MORE=MONEY →9567+1085=10652. BASE+BALL=GAMES →7483+7455=14938. >>393 Elixir # 再帰で、蓄積リスト・ary に、連結していく defmodule MyList do def add( num ), do: _add( num, [ ] ) defp _add( 0, ary ) do ary end defp _add( num, ary ) when num > 0 do _add( num - 1, List.duplicate( num, num ) ++ ary ) end end ary = MyList.add 3 IO.inspect ary #=> [1, 2, 2, 3, 3, 3] >>413 , >>412 の順に解いてね。 ヒント要る? 文字の数が少ないんだから、ブルートフォースでも解けるか。。。 間違えてなければO(10!)のはずだから充分多いのでは しかもとっさにcombination用意できなければ(vimなどで)for文10個書いたほうが早いまである 覆面算を制約論理プログラム iZ-Cを使って解きます。の記事があります。 https://sunasunax.hatenablog.com >>393 Perl5 use feature qw{signatures}; sub f($n) { $n ? (f($n-1), ($n) x $n) : () } @a = f(3); print "@a\n"; 実行結果 ~ $ perl 18_393_inc_ary.pl The signatures feature is experimental at 18_393_inc_ary.pl line 2. 1 2 2 3 3 3 >>393 Perl5、単にmapで値個数要素のリストに展開 $n = 3; @a = map{($_) x $_} 1..$n; print "@a\n"; j実行結果 ~ $ perl 18_393_inc_ary_map.pl 1 2 2 3 3 3 >>393 python lambda x: [int(i) for i in "".join(f"{y}"*y for y in range(1,x+1))] 全く知らない構文の言語でカンでいじっても構文エラーも止められずに 動かない機械ガチャガチャしてるだけ感すごいよな お題: テキストファイル「input.txt」の中の" dot "を"."に置換し、さらに" at "を"@"に置換したときに、RFCに従ったメールアドレスになる部分文字列を抽出し、そのメールアドレスのリストを改行区切りで出力せよ。 >>393 Ruby def f(n) (1..n*(n+1)/2).map{|x| ((x*2)**0.5+0.5).to_i} end >>430 テスト用のinput.txtちょーだい! >>432 「これはテキトーなテキストデータである。 例えば user at example dot com とか user at example dot co dot jp とか katayama dot hirofumi dot mz at example dot net とかあるでしょ。 詐欺メールに引っ掛からないためには、URLのドメインを確認することが一番。 google.com google.co.jp まあ、いろいろあるっしょ。」 >>430 Mail::RFC822::Address: regexp-based address validatio http://www.ex-parrot.com/ ~pdw/Mail-RFC822-Address.html >>393 Python3 (n, a) = (3, []) for i in range(1, n+1): a.extend([i] * i) print(a) 実行結果 ~ $ python 18_393_incary.py [1, 2, 2, 3, 3, 3] >>395 Ruby def f(s,d) eval("['"+s.gsub(d,"','")+"']") end p f("1 2 3 4"," ") 実行結果 ["1", "2", "3", "4"] お題: バイナリファイルを読み込んで各バイトの各ビットについて、上位ビットから順に、ゼロをシフトJISの半角カナの「タ」に、いち(1)を同じくの「ヒ」に変換する変換器。 >>443 追記。逆変換器も作って動作することを確認せよ。 >>443 Ruby Fpath = 'test.bin' File.open( Fpath, 'wb' ){|fh| fh.write "Hello word\n" } Tbl10 = "\xC0\xCB".force_encoding(Encoding::BINARY) tb = (0..255).to_a.map{|x| ('%08b' % x).tr( '10', Tbl10 ) } buff = File.open( Fpath, 'rb' ).each_byte.map{|x| tb[x] } puts buff.join().encode( Encoding::UTF_8, Encoding::CP932 ) print buff.map{|x| x.tr( Tbl10, '10' ).to_i(2).chr }.join #=> ヒタヒヒタヒヒヒヒタタヒヒタヒタヒタタヒタタヒヒヒタタヒタタヒヒヒタタヒタタタタヒヒタヒヒヒヒヒヒタタタヒタタタヒタタヒタタタタヒタタタヒヒタヒヒタタヒヒタヒヒヒヒヒヒタヒタヒ #=> Hello word >>442 f("'", ?,) # =>SyntaxError: (eval):1: unterminated string meets end of file ['''] ^ (eval):1: syntax error, unexpected end-of-input, expecting ']' >>443 Perl5 print map{qw(ヒ タ)[$_]} map{split '', sprintf '%08b', ord} split'','Hello word'; 実行結果 ~ $ perl 18_443_タヒ.pl ヒタヒヒタヒヒヒヒタタヒヒタヒタヒタタヒタタヒヒヒタタヒタタヒヒヒタタヒタタタタヒヒタヒヒヒヒヒヒタタタヒタタタヒタタヒタタタタヒタタタヒヒタヒヒタタヒヒタヒヒ >>447 >>444 逆変換機もか…忘れてた まいいや >>443 Elixir。CP932 が無いので、途中までしか出来ません! # 8桁・2進数・0埋め _ = 'abc' |> Enum.map( fn char -> :io.format( "~8.2.0B", [ char ] ) end ) # 01100001_01100010_01100011 >>443 POSIX sh 変換 (https://paiza.io/projects/Yk6wcUtik7BZZ0AHspdZFw?language=bash ) for _b in $(od -v -A n -t d1); do printf '%b' \ "\\$(( $_b & 128 ? 300 : 313 ))" \ "\\$(( $_b & 64 ? 300 : 313 ))" \ "\\$(( $_b & 32 ? 300 : 313 ))" \ "\\$(( $_b & 16 ? 300 : 313 ))" \ "\\$(( $_b & 8 ? 300 : 313 ))" \ "\\$(( $_b & 4 ? 300 : 313 ))" \ "\\$(( $_b & 2 ? 300 : 313 ))" \ "\\$(( $_b & 1 ? 300 : 313 ))" done 逆変換 (https://paiza.io/projects/AN6vfPgtdJODnYL9jW8MDQ?language=bash ) od -v -A n -t o1 | fold -b -w 32 | while read _b8 _b7 _b6 _b5 _b4 _b3 _b2 _b1; do printf '%b' "\\$(( ($_b8 == 300 ? 200 : 0) + ($_b7 == 300 ? 100 : 0) + ($_b6 == 300 ? 40 : 0) + ($_b5 == 300 ? 20 : 0) + ($_b4 == 300 ? 10 : 0) + ($_b3 == 300 ? 4 : 0) + ($_b2 == 300 ? 2 : 0) + ($_b1 == 300 ? 1 : 0) ))" done >>443 >>444 Perl5、バイナリコード(ln)を含むデータをファイルから読み込み、変換》逆変換 undef $/; # slurp $s = <>; @b = map{qw(ヒ タ)[$_]} split'', unpack 'B*', $s; print @b, "\n"; %h = qw(ヒ 0 タ 1); $t = pack 'B*', join '', map{$h{$_}} @b; print $t; 実行結果 $ od -xc Hello_world_ln.txt 0000000 6548 6c6c 206f 6f77 6c72 0a64 H e l l o w o r l d \n $ cat Hello_world_ln.txt Hello world $ perl 18_443_444_ヒタ.pl < Hello_world_ln.txt ヒタヒヒタヒヒヒヒタタヒヒタヒタヒタタヒタタヒヒヒタタヒタタヒヒヒタタヒタタタタヒヒタヒヒヒヒヒヒタタタヒタタタヒタタヒタタタタヒタタタヒヒタヒヒタタヒタタヒヒヒタタヒヒタヒヒヒヒヒヒタヒタヒ Hello world お題 UTF-8 は以下のように、先頭ニブル・4ビットで、1〜4バイト文字を判別しています。 この法則を使って、この文字列のバイト数を求めよ あaθ💀xΩ死🄫 1バイト文字: 0000〜0111: 0〜7 多バイト文字の2バイト目以降 1000〜1011: 8〜11(8〜B) 2バイト文字: 1100〜1101: 12〜13(C〜D) 3バイト文字: 1110: 14(E) 4バイト文字: 1111: 15(F) Unicode https://seiai.ed.jp/sys/text/csd/cf14/c14a070.html ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる