プログラミングのお題スレ Part22
>>179 https://ideone.com/tvmy6F let f n p = let rec aux r p q = if p = 0 then r else aux (r + p) ((p + q) / n) ((p + q) mod n) in aux 0 p 0 let () = print_int @@ f 3 5 ↓ 7 >>179 R R <- function(N, P) ((P - 1) * N) %/% (N - 1) + 1 お題:時刻の文字列が与えられる。その時刻から1秒後の時刻を出力せよ。 例 入力:00:00:00 出力:00:00:01 入力:23:59:59 出力:00:00:00 >>187 Perl5 use Time::Piece; use Time::Seconds; for (qw{00:00:00 23:59:59}) { $t = Time::Piece->strptime($_, '%T') + 1; print "入力:$_\n出力:", $t->strftime('%T'), "\n"; } ※見易くするためインデントを全角スペースに置換してあります 実行結果 ~ $ perl 22_187_1秒後.pl 入力:00:00:00 出力:00:00:01 入力:23:59:59 出力:00:00:00 >>188 use Time::Seconds; これ要らなかった…orz >>187 octave https://ideone.com/CEGEj8 f = @(s) datestr(addtodate(datenum(s), 1, 'second'), 'HH:MM:SS'); in = ['00:00:00';'23:59:59'], out = f(in) >>187 PowerShell "00:00:00", "23:59:59" |% {[String]([DateTime]$_).AddSeconds(1).TimeOfDay} >>187 ruby https://ideone.com/y2wgxo require 'time' f = -> s {(Time.parse(s) + 1).strftime('%T')} p ['00:00:00', '23:59:59'].map {|s| [s, f.(s)]} >>187 js const decode = (s) => s.split(":").map(Number); const encode = (nums) => nums.map((v) => String(v).padStart(2, "0")).join(":"); const inct = (s, sec = 1) => { const a = decode(s); const ss = [ { n: a[0], max: 24 }, { n: a[1], max: 60 }, { n: a[2], max: 60 }, ]; let up = sec; const b = ss .reverse() .map(({ n, max }) => { n += up; up = Math.floor(n / max); return n % max; }) .reverse(); return encode(b); }; console.log(inct("00:00:00"));// 00:00:01 console.log(inct("23:59:59"));// 00:00:00 console.log(inct("00:00:00", 100));// 00:01:40 >>187 ocaml https://ideone.com/aEsvl6 let sec_of_hms hms = let at i = int_of_string (String.sub hms i 2) in at 0 * 60 * 60 + at 3 * 60 + at 6 let hms_of_sec sec = Printf.sprintf "%02d:%02d:%02d" (sec mod 86400 / 3600) (sec mod 3600 / 60) (sec mod 60) let (<<) f g x = f (g x) let f = hms_of_sec << (+) 1 << sec_of_hms >>187 Rust (date/timeライブラリ不使用版) fn next_time(cur: &str) -> String { let [sec, min, hour] = cur .rsplitn(3, ':') .map(|s| s.parse().unwrap()) .zip([60, 60, 24]) .scan(1, |carry, (mut value, limit)| { value += *carry; (*carry, value) = if value == limit { (1, 0) } else { (0, value) }; Some(value) }) .collect::<ArrayVec<_, 3>>()[..] else { unreachable!() }; format!("{hour:02}:{min:02}:{sec:02}") } fn main() { assert_eq!(next_time("00:00:00"), "00:00:01"); assert_eq!(next_time("23:59:59"), "00:00:00"); } >>187 Kotlin 今度は Java のライブラリは使わずに時分秒を保持するクラスを自分で作ってそこで秒に足すとか文字列にするとかやるようにした。 https://paiza.io/projects/7YcPDBTxVFt9EVczvBJ8gQ >>187 dart 2.3.0 https://ideone.com/khq9gr void main() { var sec_of_hms = (hms) => hms.split(':').fold(0, (acc, s) => acc * 60 + int.parse(s)); var hms_of_sec = (sec) => [sec % 86400 ~/ 3600, sec % 3600 ~/ 60, sec % 60].map((x) => x.toString().padLeft(2, '0')).join(':'); var f = (hms) => hms_of_sec(sec_of_hms(hms) + 1); print(f('00:00:00')); print(f('23:59:59')); } >>187 c https://ideone.com/wRIYl2 int hmstosec(const char *hms) { int h, m, s; return sscanf(hms, "%d:%d:%d", &h, &m, &s) == 3 ? h * 3600 + m * 60 + s : 0; } char *sectohms(char *buff, int sec) { sprintf(buff, "%02d:%02d:%02d", sec % 86400 / 3600, sec % 3600 / 60, sec % 60); return buff; } char *f(char *buff, const char *hms) { return sectohms(buff, hmstosec(hms) + 1); } >>187 c https://ideone.com/3gj90n int hmstosec(const char *hms) { #define _(i) ((hms[i] - '0') * 10 + (hms[i + 1] - '0')) return _(0) * 3600 + _(3) * 60 + _(6); #undef _ } char *sectohms(char *buff, int sec) { #define _(i, value) buff[i] = '0' + (value) / 10, buff[i + 1] = '0' + (value) % 10 return _(0, sec % 86400 / 3600), buff[2] = ':', _(3, sec % 3600 / 60), buff[5] = ':', _(6, sec % 60), buff[8] = '\0', buff; #undef _ } char *f(char *buff, const char *hms) { return sectohms(buff, hmstosec(hms) + 1); } >>187 gawk https://ideone.com/zBy22y BEGIN {FS=":"} {print strftime("%T", mktime(sprintf("2024 01 23 %s %s %s", $1, $2, $3)) + 1);} >>187 sqlite https://ideone.com/fjEdMz select time('00:00:00', '+1 second'); select time('23:59:59', '+1 second'); >>187 bash https://ideone.com/pYf8vL while read hms; do date '+%T' --date="+1 seconds $hms" done >>187 pascal https://ideone.com/sprmCC program ideone; Uses sysutils, dateutils; function f(hms : string) : string; begin f := TimeToStr(IncSecond(StrToTime(hms), 1)) end; begin writeln(f('00:00:00')); writeln(f('23:59:59')); end. >>187 を時間ライブラリ無しで作成できている言語は現時点で 193のJavaScript 194のOCaml 195のRust 197のKotlin 198のDart 199のC++ 200のC 201のLisp 以上 >>187 Perl bashのコマンドラインから長い長いワンライナーで。 $ perl -ne 'if(/(\d+):(\d+):(\d+)/){$h=$1;$m=$2;$s=$3;printf"入力:%02d:%02d:%02d\n",$h,$m,$s;$s++;if($s>=60){$m++;$s=0;if($m>=60){$h++;$m=0;if($h>=24){$h=0}}}printf"出力:%02d:%02d:%02d\n",$h,$m,$s}' 1:2:3 入力:01:02:03 出力:01:02:04 0:0:0 入力:00:00:00 出力:00:00:01 23:59:59 入力:23:59:59 出力:00:00:00 $ お題 入力データをグループ分けして出力せよ 入力データの、= の左右は同じグループである。 出力する順番は、入力データの出現順とする UnionFind を使えば良いかも 入力データ ["a1=a2", "b1=b2", "b3=b2", "c1=c2", "e1=e2", "a3=a4", "c3=c4", "e1=e3", "a2=a4", "c3=c1", "b3=a4", "c2=d1", "a4=a5", "d2=c1", "b4=b3", "d3=c3"] 出力 [["a1", "a2", "b1", "b2", "b3", "a3", "a4", "a5", "b4"], ["c1", "c2", "c3", "c4", "d1", "d2", "d3"], ["e1", "e2", "e3"]] Ruby で、UnionFind を自作してみた。 下はユニットテストです https://paiza.io/projects/e6nk1EOu3utyWpV3iuWAFQ?language=ruby https://paiza.io/projects/kjeVtTKeDwEnWVrBU5_nbg?language=ruby >>206 Rust fn foo<'a, 'b>(input: &'b [&'a str]) -> Vec<Vec<&'a str>> { struct Data<'a> { name: &'a str, rep: usize, coll: Option<Vec<usize>>, } let mut data = Vec::<Data>::new(); let mut map = HashMap::<&str, usize>::new(); for s in input { let (index0, index1) = s.splitn(2, '=') .map(|s| match map.get(s) { Some(&index) => data[index].rep, None => { let index = data.len(); map.insert(s, index); data.push(Data { name: s, rep: index, coll: Some(vec![index]), }); index }, }) .sorted().tuple_windows().next().unwrap(); if index0 != index1 { let coll0 = data[index0].coll.take().unwrap(); let coll1 = data[index1].coll.take().unwrap(); coll1.iter().for_each(|&index| data[index].rep = index0); data[index0].coll = Some(itertools::merge(coll0, coll1).collect()); } } data.iter().map(|data| &data.coll).flatten() .map(|coll| coll.iter().map(|&index| data[index].name).collect()).collect() } >>207 の動作確認用追加分 use std::collections::HashMap; use itertools::Itertools; fn main() { let input = [ "a1=a2", "b1=b2", "b3=b2", "c1=c2", "e1=e2", "a3=a4", "c3=c4", "e1=e3", "a2=a4", "c3=c1", "b3=a4", "c2=d1", "a4=a5", "d2=c1", "b4=b3", "d3=c3" ]; let output = [ vec!["a1", "a2", "b1", "b2", "b3", "a3", "a4", "a5", "b4"], vec!["c1", "c2", "c3", "c4", "d1", "d2", "d3"], vec!["e1", "e2", "e3"] ]; assert_eq!(foo(&input), output); } >>206 ruby https://ideone.com/eF5lww f = -> a { w = a.map {|s| s.split('=')}.flatten.uniq.map.with_index.to_h a.each_with_object([]) {|s, acc| x, xa, y, ya = s.split('=').map {|k| [k, acc.find {|b| b.include? k}]}.flatten(1) if xa && ya then xa.concat (acc.delete ya) << x << y elsif xa then xa << x << y elsif ya then ya << x << y else acc << [x, y] end }.map {|a| a.uniq.sort_by {|s| w[s]}}.sort_by {|a| w[a[0]]} } >>206 rust https://ideone.com/MEZMPO fn f<'a>(a: &[&'a str]) -> Vec<Vec<&'a str>> { // ' let h = a.iter().map(|&s| s.split('=')).flatten().rev().enumerate().map(|(p, s)| (s, p)).collect::<HashMap<_, _>>(); let mut acc = Vec::<Vec<&str>>::new(); for xy in a.iter().map(|s| s.split('=').collect::<Vec<_>>()) { match (acc.iter().position(|b| b.contains(&xy[0])), acc.iter().position(|b| b.contains(&xy[1]))) { (Some(xi), Some(yi)) => { let ys = acc[yi].clone(); acc[xi].extend(ys); acc[xi].extend(xy); acc.remove(yi); }, (Some(xi), None) => acc[xi].extend(xy), (None, Some(yi)) => acc[yi].extend(xy), _ => acc.push(xy), } } for b in acc.iter_mut() { b.sort_by(|c, d| h.get(d).cmp(&h.get(c))); b.dedup(); } acc.sort_by(|c, d| h.get(d[0]).cmp(&h.get(c[0]))); acc } >>206 ruby https://ideone.com/daI0QL ・若干の修正 f = -> a { w = a.map {|s| s.split('=')}.flatten.uniq.map.with_index.to_h a.each_with_object([]) {|s, acc| x, xa, y, ya = s.split('=').map {|k| [k, acc.find {|b| b.include? k}]}.flatten(1) if xa && ya then xa.concat (acc.delete ya) elsif xa then xa << y elsif ya then ya << x else acc << [x, y] end }.map {|a| a.sort_by {|s| w[s]}}.sort_by {|a| w[a[0]]} } >>206 rust https://ideone.com/dO4xea ・若干の修正 fn f<'a>(a: &[&'a str]) -> Vec<Vec<&'a str>> { // ' let h = a.iter().map(|&s| s.split('=')).flatten().rev().enumerate().map(|(p, s)| (s, p)).collect::<HashMap<_, _>>(); let mut acc = Vec::<Vec<&str>>::new(); for xy in a.iter().map(|s| s.split('=').collect::<Vec<_>>()) { match (acc.iter().position(|b| b.contains(&xy[0])), acc.iter().position(|b| b.contains(&xy[1]))) { (Some(xi), Some(yi)) => { let ys = acc[yi].clone(); acc[xi].extend(ys); acc.remove(yi); }, (Some(xi), None) => acc[xi].push(xy[1]), (None, Some(yi)) => acc[yi].push(xy[0]), _ => acc.push(xy), } } acc.iter_mut().for_each(|b| b.sort_by(|c, d| h.get(d).cmp(&h.get(c)))); acc.sort_by(|c, d| h.get(d[0]).cmp(&h.get(c[0]))); acc } >>208 Perl5 use feature qw{:5.16 signatures}; no warnings qw(experimental::signatures); @s = qw[a1=a2 b1=b2 b3=b2 c1=c2 e1=e2 a3=a4 c3=c4 e1=e3 a2=a4 c3=c1 b3=a4 c2=d1 a4=a5 d2=c1 b4=b3 d3=c3]; for (map{[sort /(\w+)=(\w+)/]} @s) { ($l, $r) = @$_; $g{$r} //= $g{$l} //= $g{$r} // $l; $h{$g{$r}} = $g{$l} if $g{$l} ne $g{$r}; } $h{$k} = sub($e){$h{$e} ? __SUB__->($h{$e}) : $e}->($v) while ($k, $v) = each %h; $g{$_} = $h{$g{$_}} // $g{$_} for keys %g; push @{$r{$v}}, $k while ($k, $v) = each %g; say "@$_" for values %r; ※見易くするためインデントを全角スペースに置換してあります 実行結果 $ perl 22_206_grouping.pl b3 a3 a5 b4 a4 a1 b1 a2 b2 c1 d1 d3 c3 c2 d2 c4 e3 e1 e2 >>208 宛てじゃなかった >>206 の回答だったわ… orz >>206 >>215 をPowerShellに移植 $in = "a1=a2", "b1=b2", "b3=b2", "c1=c2", "e1=e2", "a3=a4", "c3=c4", "e1=e3", "a2=a4", "c3=c1", "b3=a4", "c2=d1", "a4=a5", "d2=c1", "b4=b3", "d3=c3" $in -split "=" |% {$h = @{}; $n = 0} {if (!$h[$_]) {$h[$_] = $n++}} $eq = $in |% {, $h[$_ -split "="]} $g = 1..$n do { $changed = $false $eq |% { $i, $j = $_ switch ($g[$i] - $g[$j]) { {$_ -gt 0} {$g[$i] = $g[$j]; $changed = $true} {$_ -lt 0} {$g[$j] = $g[$i]; $changed = $true} } } } while ($changed) $h.keys | sort {$h[$_]} | group {$g[$h[$_]]} |% {"[$($_.group -join ", ")]"} -- 実行結果 -- [a1, a2, b1, b2, b3, a3, a4, a5, b4] [c1, c2, c3, c4, d1, d2, d3] [e1, e2, e3] >>218 の5行目の if (!$h[$_]) を if ($h[$_] -eq $null) に訂正 >>206 ruby https://ideone.com/2UiT8U ・>>211 から若干のアレンジ ・同一グループの収集にSortedSetを使用 >>206 Kotlin 入力データを標準入力から入力したり、クラス作ってその中でまとめる等、色々やって長くなった。 https://paiza.io/projects/zdysD5ygRDFVbY2gAGCwOw >>206 ruby https://ideone.com/j2xPyB ・>>221 から若干のアレンジ ・SortedSet単位でのみいじるようにした f = -> a { g = -> a {a.combination(2) {|x, y| break g.(a.tap {x.merge y; a.delete y}) if x.intersect? y}} h = a.map {|s| s.split('=')}.flatten.uniq.map.with_index.to_h a = a.map {|s| s.split('=').map {|k| h[k]}.to_set SortedSet} g.(a).map {|set| set.map &h.invert.method(:[])} } >>206 rust https://ideone.com/Ma1WGV ・>>223 の移植 ・色々迷いアリ .map(|k| *h.get(k).unwrap())のところは当初 .map(|k| h.get(k).map(|&i| i)).flatten()などとしていたが 正解がわからないので迷った挙げ句に短く書けるほうを採用 ・これに限らずrustは不慣れなので色々珍妙なことをしている可能性アリ >>206 rust https://ideone.com/m5INyJ ・>>225 から若干の修正 ・不必要なループ回数を訂正 ・二重forを一重に(でもかえって煩雑に) ・まだまだ迷いアリ .map(|k| *h.get(k).unwrap())は結局 .flat_map(|k| h.get(k)).cloned()に置き換え こっちのほうが個人的にはスッキリ感アリ >>206 rust https://ideone.com/hT5zGF ・上記のmutナシ版 ・パフォーマンス的な観点もナシ >>226 すべてruby移植版rust DでもE見た目派生まとめ mutあり版 https://ideone.com/m5INyJ // for if return https://ideone.com/R8wcOJ // match find https://ideone.com/ifI5EX // if let find mutなし版 https://ideone.com/hT5zGF // for if return https://ideone.com/1PNKbR // match find https://ideone.com/btKWb1 // if let find 集合同士の組み合わせに重なりが一個もなかったときに 最後に返す a がポツーンと片隅に居るのが落ち着かなかったので match/if letで書き直してみたがそれはそれで難があり? 条件部分が奥に入ってしまったのがなんかイヤだったり? 一行目が長くなりすぎる、という理由で二行に分けたり? やっぱ元のfor if returnのリズムのほうが眼球に入りやすい? >>206 >>230 をDで書くと https://ideone.com/9oenyq になるが、switch case 0, 1, 2の場合も3の場合と同じ処理にすると、効率は落ちるもののかなり短くできる。 https://ideone.com/ILLUdy >>206 octave https://ideone.com/VtqJcV ・組み合わせつくって集合のペアごとに調べることをやめた ・集合間で重複する要素に着目して集合を減らすようにした >>223 g.(a).map {|set| set.map &h.invert.method(:[])}じゃなくて単に g.(a).map {|set| h.keys.values_at *set}で良かった お題:数値が入力されるのでその数値に最も近い回分数を出力せよ 回分数とは回分になっている数(負数含まず)のことである 最も近い回分数が2つある場合は2つとも出力せよ 入力 0 出力 0 入力 17 出力 22 入力 100 出力 99 出力 101 >>234 Rust fn foo(n: usize) -> (usize, Option<usize>) { let n2b = |n: usize| { let mut o = Some(n); iter::from_fn(|| { let n = o.take()?; o = (n >= 10).then(|| n / 10); Some((n % 10) as i8) }).collect::<Vec<i8>>() }; let b2n = |b: &[i8]| b.iter().rev().fold(0_usize, |n, b| n * 10 + *b as usize); let pal = |b: &mut [i8]| { let len = b.len() / 2; let (l, u) = b.split_at_mut(len); iter::zip(l, u.iter().rev()).for_each(|(l, u)| *l = *u); }; let inc = |b: &mut [i8]| { let len = b.len() / 2; let mut c = 1; b[len..].iter_mut().for_each(|b| { *b += c; if *b > 9 { *b = 0; c = 1; } else { c = 0; }}); }; let dec = |b: &mut [i8]| { let len = b.len() / 2; let mut c = 1; b[len..].iter_mut().for_each(|b| { *b -= c; if *b < 0 { *b = 9; c = 1; } else { c = 0; }}); }; let fix = |b: &mut [i8]| { if b.last() == Some(&0) { if b.len() & 1 == 0 { b[(b.len() - 1) / 2] = 9; } true } else { false } }; let mut b = n2b(n); pal(&mut b); let n1 = b2n(&b); match n.cmp(&n1) { Ordering::Equal => return (n, None), Ordering::Greater => inc(&mut b), Ordering::Less => dec(&mut b), } if fix(&mut b) { b.pop(); } pal(&mut b); let n2 = b2n(&b); match n.abs_diff(n1).cmp(&n.abs_diff(n2)) { Ordering::Less => (n1, None), Ordering::Greater => (n2, None), Ordering::Equal => (n1, Some(n2)), } } >>234 >>237 は入力が1〜9のとき出力が正しくなかった。function内の1行目に if ($n -le 9) {return $n} を 挿入すると修正される。 Rでは添字の開始値は1で添字0では空のデータが返るので、入力が1〜9のときの場合分けは不要。 []演算子と+演算子を文字列でも使えるように再定義した。 https://ideone.com/PP5swB Dでは添字範囲指定は半開区間なので、入力が1〜9のときの場合分けは不要。 https://ideone.com/hvNBia >>234 Perl5 for $n (0,17,100,123459321) { my %a; for (0..$n) { $i = $n - $_; $a{$i} = $i if 0 <= $i and $i =~ /^((\d)(?1)\2|\d?)$/; $j = $n + $_; $a{$j} = $j if $j =~ /^((\d)(?1)\2|\d?)$/; last if keys %a; } @a = keys %a; print "$n -> @a\n"; } ※見やすくするためインデントを全角スペースに置換してあります。 実行結果 $ perl 22_234_palindromic_number.pl 0 -> 0 17 -> 22 100 -> 99 101 123459321 -> 123464321 123454321 >>241 last if keys %a; } @a = keys %a; は last if @a = keys %a; } とコンパクトに書けるんだった、まぁいいや >>234 Perl5、小さい方の検索は0で止まるので負の値を避ける必要はなかった、書き直し。 $r = qr/^((\d)(?1)\2|\d?)$/; for $n (0,17,100,123459321) { my %a; for (0..$n) { $a{$n - $_} = 1 if ($n - $_) =~ $r; $a{$n + $_} = 1 if ($n + $_) =~ $r; last if @a = keys %a; } print "$n -> @a\n"; } >>234 Kotlin 何か画期的なアルゴリズムを使ったわけではなく、むしろほとんど何も考えずただ作られただけのプログラム。 https://paiza.io/projects/S5qsLnHz_pZD3um9jYRg_Q >>234 Python3 def f(k): s = str(k) return s == s[::-1] for n in [0, 17, 100, 123459321]: l = set() for i in range(n + 1): if f(n - i): l.add(n - i) if f(n + i): l.add(n + i) if l: print(n, l) break ※見易くするためインデントは全角空白に置換してあります 実行結果 $ python3 22_234_palindromic_number..py 0 {0} 17 {22} 100 {99, 101} 123459321 {123454321, 123464321} >>251 >[[0, [0]], [17, [11]], [100, [99, 101]]] 17 は、22 だよ >>235 しらみ潰しで失格 >>236 しらみ潰しで失格 >>240 しらみ潰しで失格 >>243 しらみ潰しで失格 >>244 しらみ潰しで失格 >>245 しらみ潰しで失格 >>246 しらみ潰しで失格 >>247 しらみ潰しで失格 >>248 しらみ潰しで失格 >>250 しらみ潰しで失格 >>251 しらみ潰しで失格 >>234 ruby https://ideone.com/N0w91j f = -> n { (0..n).lazy.map {|i| [n - i, n + i].select {|x| x.to_s.reverse.to_i == x}}.find(&:any?).uniq } >>252 (`・ω・´)ゞ 誤:a - 1, a + 1 正:a - 1, b + 1 >>234 dart https://ideone.com/e23wRv void main() { var rev = (n) => int.parse(n.toString().split('').reversed.join()); var f = (n) => Iterable.generate(n + 1).map((i) => [n - i, n + i].where((x) => x == rev(x))).firstWhere((a) => a.isNotEmpty).toSet().toList(); print([0, 17, 100].map((n) => [n, f(n)])); } しらみ潰しとは例えば1から順番に見つかるまで全てを試していく最悪な方法を指す 今回の場合だと与えた数から順番に見つかるまで±1を続けて全てを試していって探すプログラムが該当する >>262 私は >>248 だけれども、解法としてはそれしかないと思いますね >>249 と >>238 は しらみ潰しではなく きちんとプログラミングして算出しているようにみえますね >>264 私は解答は提出していないが、ざっくりと自分が思いついた方法 まず、以下のような操作を考える A. 1234という入力に対して1234321を返す B. 1234という入力に対して12344321を返す ここで、xという入力に対してA,Bが返す数をA(x),B(x)と表すことにする 次に、与えられた数の桁数で場合分け (1)与えられた数字の桁数が奇数の場合 例として5桁の数字を考える N=a*10000+b*1000+c*100+d*10+e*1 (a~eは1桁の自然数, aは0でない) が与えられたとき、 M=a*100+b*10+c*1 とすると、N=10000の場合を除いて、Nに最も近い回文数は A(M), A(M+1), A(M-1) の3つの候補に絞られる(厳密にはA(M)とNとの大小比較からA(M±1)の何れかは明らかに候補にならないので2つを考えれば良い) N=10000の場合は9999と10001が答え (2)与えられた数の桁数が偶数の場合 例として6桁の数を考える (1)と同様に N=a*100000+b*10000+c*1000+d*100+e*10+f*1 に対して M=a*100+b*10+c*1 とすると、N=100000の場合を除いて B(M), B(M+1), B(M-1) のどれかがNに最も近い回文数(厳密には以下略) N=100000の場合は99999と100001が答え 十分大きな数に対しては虱潰しに回文判定していくより速く求まる >>259 Iterable.generate(n).map(f)は単に Iterable.generate(n, f)で良かったと判明 >>234 >>249 をC++で書き換え(入力値は64ビット整数の範囲内限定) https://ideone.com/e1AM8A 元々はCで書き、4行目はなし、15行目と24行目はstrrev(s + i);だったが、Windowsのgccでは コンパイルできたのにideoneではできなかったので、仕方なくC++にしてstd::reverseで代用した。 >>234 Rust fn nearest_palindrome_numbers(n: usize) -> Vec<usize> { let mut dd = DecimalDigits::new(n); dd.palindrome_using_upper_half(); let n1 = dd.to_number(); match compare(n, n1) { Equal => return vec![n], Greater => dd.increment_upper_half(), Less => dd.decrement_upper_half(), } if dd.is_most_upper_zero() { return vec![n - 1, n + 1]; } dd.palindrome_using_upper_half(); let n2 = dd.to_number(); match compare_absolute_diff((n, n1), (n, n2)) { Less => return vec![n1], Greater => return vec![n2], Equal => return if n1 < n2 { vec![n1, n2] } else { vec![n2, n1] }, } } >>267 N=17=1*10+7*1のとき、Nは2桁(偶数桁)でM=1*1=1 B(M)=B(1)=11はNより小さいのでB(M-1)は考えなくてよい B(M+1)=B(2)=22なので11,22が答えの候補 11より22のほうが17に近いので22が答え ちょっとNに対するMの説明が足りてなかったけど言葉で上手く言い表せないすみません(上位半分以上かつ最小の桁数を抜き出す、的な) >>234 >>269 の一部でC++の機能をどうせ使ってしまったので、この際、全部をC++流に変えたら C流よりすっきり書けた。 https://ideone.com/38bo2E >>273 > [1000, [1001]] 誤:ps = [p.(s), p.(t.to_i.pred.abs.to_s + u), p.(t.succ + u)] 正:ps = [p.(s), p.(t.to_i.pred.abs.to_s + u), p.(t.succ + u), p.(s.to_i.pred.abs.to_s)] とりあえず雑に修正してみたが? (ノ∀`)アチャー >>262 >>245 のKotlinのプログラムは何も考えてなくて本当に馬鹿正直に±1して一つ一つ検査する方式で作ったんだけど、それでもあなたのテストではダメということになったの? まあ Int (符号付32bit整数) 使ってるからその限界超えたらダメではあるんだけど、そういう問題ではなく? >>276 それはしらみつぶしと言われる駄目プログラミングだよ 例えば求める解法が存在する方程式を解くのに値を±1しながら順に代入して試していくのと同じ >>277 あー。プログラムにバグがあってまともに答えが出ないっていうことではなく何の捻りもないプログラムだからダメっていう感想ね。それならわかる。 こちらもアルゴリズム思い浮かばないけどとりあえず作ってみただけだし。ダメというほどではないが良いとも思えないプログラムなので。 >>234 ruby https://ideone.com/E9VSE3 ・273の[1000, [1001]]バグ修正版 ・275とは違う方法で修正してみたがやっつけ感大 >>234 ruby 2.5.5 https://ideone.com/1zqSr1 ・いわゆる(?)ジェネレータ版 ・「終端を持たない範囲オブジェクト」はRuby 2.6.0から >>234 ruby 2.5.5 https://ideone.com/04fxGM ・ジェネレータ版ちょっとアレンジ ・to_sしてto_iするのをやめた 異なる自然数 a, b (a > b) における a^3 - b^3 を「a, b の三乗差」と呼ぶことにする。 異なる5通りの組(a, b) (c, d) ... (j, k) について三乗差がすべて相等しいとき その組(a, b)...(j, k) および三乗差自体を求めよ 異なる6通りの組で三乗差が相等しい場合があるかも検討せよ >>282 [(1134, 357), (1155, 504), (1246, 805), (2115, 2004), (4746, 4725)] a^3 - b^3 == 1412774811 read.cgi ver 07.5.1 2024/04/28 Walang Kapalit ★ | Donguri System Team 5ちゃんねる