プログラミングのお題スレです。
【出題と回答例】
1 名前:デフォルトの名無しさん
お題:お題本文
2 名前:デフォルトの名無しさん
>>1 使用言語
回答本文
結果がある場合はそれも
【ソースコードが長くなったら】 (オンラインでコードを実行できる)
https://ideone.com/
http://codepad.org/
http://compileonline.com/
http://rextester.com/runcode
https://runnable.com/
https://code.hackerearth.com/
http://melpon.org/wandbox
https://paiza.io/
宿題は宿題スレがあるのでそちらへ。
※前スレ
プログラミングのお題スレ Part21
https://mevius.5ch.net/test/read.cgi/tech/1668333636/
プログラミングのお題スレ Part22
1デフォルトの名無しさん
2023/08/03(木) 13:52:13.20ID:/xW45k0z719デフォルトの名無しさん
2025/03/30(日) 15:24:52.85ID:6QsLEZYT720デフォルトの名無しさん
2025/03/30(日) 15:35:52.69ID:bQF7/1H+ 後者で学校の課題な予感がするな
721デフォルトの名無しさん
2025/03/30(日) 20:11:24.72ID:qyCZpZxd >>718
R Version4
https://ideone.com/r03zEZ
ideoneのRは古すぎてエラーが出てしまうので、出力は入力欄に記載した。
巨大整数型を使わなければideoneでも実行できる。
https://ideone.com/K0RefY
R Version4
https://ideone.com/r03zEZ
ideoneのRは古すぎてエラーが出てしまうので、出力は入力欄に記載した。
巨大整数型を使わなければideoneでも実行できる。
https://ideone.com/K0RefY
722デフォルトの名無しさん
2025/03/30(日) 20:58:57.54ID:qyCZpZxd723 警備員[Lv.4]
2025/03/31(月) 03:24:21.45ID:V+SeThnI724デフォルトの名無しさん
2025/03/31(月) 05:32:04.89ID:lZyiUZP+ >>718
学校の課題をここに書くなって教わらなかったの?
学校の課題をここに書くなって教わらなかったの?
725デフォルトの名無しさん
2025/03/31(月) 22:37:26.59ID:eEIz6yDp >>718
>>721-722を整理して行列とヴェクトルの積ですっきり書けるようにした。
R (ideoneでも巨大整数型で実行可能になった)
https://ideone.com/sHNag3
C++
https://ideone.com/7zgflb
式を展開してしまえばPowerShellで結局これだけ。
$a, $b, $c, $d, $e, $f = 0, 1, 1, 2, 2, [BigInt]4
2..100 |% {
$a = 10 * $a + 5 * $b + 2 * $c + 2 * $d + $e
$b = 5 * $b + 3 * $c + $e + $f
$c = 5 * $c + $f
$d = 8 * $d + 4 * $e + 2 * $f
$e = 4 * $e + 2 * $f
$f = 4 * $f
for ($p = $a; $p % 10 -eq 0; $p /= 10) {}
"P[$_] = 0.$p"
}
>>721-722を整理して行列とヴェクトルの積ですっきり書けるようにした。
R (ideoneでも巨大整数型で実行可能になった)
https://ideone.com/sHNag3
C++
https://ideone.com/7zgflb
式を展開してしまえばPowerShellで結局これだけ。
$a, $b, $c, $d, $e, $f = 0, 1, 1, 2, 2, [BigInt]4
2..100 |% {
$a = 10 * $a + 5 * $b + 2 * $c + 2 * $d + $e
$b = 5 * $b + 3 * $c + $e + $f
$c = 5 * $c + $f
$d = 8 * $d + 4 * $e + 2 * $f
$e = 4 * $e + 2 * $f
$f = 4 * $f
for ($p = $a; $p % 10 -eq 0; $p /= 10) {}
"P[$_] = 0.$p"
}
726デフォルトの名無しさん
2025/04/01(火) 22:39:42.98ID:9GVSWQu0 半角スペースの意味がわからない
そういうこだわりは古臭いよ
そういうこだわりは古臭いよ
727デフォルトの名無しさん
2025/04/02(水) 13:29:35.55ID:k9Y5euIy いまどきのプログラミングなら出力はHTMLだよな
728デフォルトの名無しさん
2025/04/02(水) 13:47:27.57ID:hi8l+lAW PHPさえその動作禁止だぞ
729デフォルトの名無しさん
2025/04/02(水) 14:31:23.27ID:vIYRPSqy >>725
変数名がa、b、cの時点でプロじゃねえな
変数名がa、b、cの時点でプロじゃねえな
730デフォルトの名無しさん
2025/04/02(水) 15:10:39.64ID:hi8l+lAW 行列演算は数学でもa,b,c,dだから…
731デフォルトの名無しさん
2025/04/02(水) 19:51:02.16ID:7MGV8+qg 俺が言ってるのは5chのプロじゃねえなってことだから
数学は関係ない
数学は関係ない
732デフォルトの名無しさん
2025/04/02(水) 19:56:31.51ID:/hTkauy0 5chのプロ 笑
733デフォルトの名無しさん
2025/04/02(水) 20:14:17.34ID:ZWpp3MuE 5chのプロはどんな変数名使うのか教えて
734デフォルトの名無しさん
2025/04/02(水) 21:11:27.43ID:HCJVcqu8 >>726
>>725の全角空白のこと? 項の書き忘れや書き間違いがないか分かりやすくするため。余分な空白や長い変数名が
ディスク・メモリ空間やコンパイル・インタプリト時間を無駄に増やすと気にする方が古臭くない?
とはいえ、今でもインタプリタ言語のPowerShellでは変数名を長くすると顕著に遅くなる。例えば、
$t1 = measure-command {for ($i = 0; $i -lt 1000000; $i++) {}}
$t2 = measure-command {for ($AnExtraordinarilyLongVariableName = 0; $AnExtraordinarilyLongVariableName -lt 1000000; $AnExtraordinarilyLongVariableName++) {}}
$t2.Ticks / $t1.Ticks
をPowerShell Ver.7で実行すると1.56前後の値が表示される。奇妙なことに、かなり古いVer.2では1前後の値になる。
実時間ではVer.7の$t2とVer.2の$t2が同程度なので、Ver.7では短い変数名での最適化が施されているということか。
それはさておき、>>712を解く人はいませんか?
>>725の全角空白のこと? 項の書き忘れや書き間違いがないか分かりやすくするため。余分な空白や長い変数名が
ディスク・メモリ空間やコンパイル・インタプリト時間を無駄に増やすと気にする方が古臭くない?
とはいえ、今でもインタプリタ言語のPowerShellでは変数名を長くすると顕著に遅くなる。例えば、
$t1 = measure-command {for ($i = 0; $i -lt 1000000; $i++) {}}
$t2 = measure-command {for ($AnExtraordinarilyLongVariableName = 0; $AnExtraordinarilyLongVariableName -lt 1000000; $AnExtraordinarilyLongVariableName++) {}}
$t2.Ticks / $t1.Ticks
をPowerShell Ver.7で実行すると1.56前後の値が表示される。奇妙なことに、かなり古いVer.2では1前後の値になる。
実時間ではVer.7の$t2とVer.2の$t2が同程度なので、Ver.7では短い変数名での最適化が施されているということか。
それはさておき、>>712を解く人はいませんか?
735デフォルトの名無しさん
2025/04/02(水) 23:31:04.18ID:vIYRPSqy >>734
縦に揃えるのは無駄に横に長くなる
縦に揃えるのは無駄に横に長くなる
736デフォルトの名無しさん
2025/04/02(水) 23:33:04.35ID:vIYRPSqy >>734
ループは毎回、構文を解析しているわけじゃねえぞ?
ループは毎回、構文を解析しているわけじゃねえぞ?
737 警備員[Lv.5]
2025/04/05(土) 14:46:26.08ID:bpkT9prW >>719
このお題の場合は数学的に答えを出そうとするとプログラムを作る必要がなくなってしまわないか?
人が普通に数学的に考えて行くと答えが出てしまいそうな気がするんだが。
またはAIに聞いたらすぐ答えが出そうな感じが。
このお題の場合は数学的に答えを出そうとするとプログラムを作る必要がなくなってしまわないか?
人が普通に数学的に考えて行くと答えが出てしまいそうな気がするんだが。
またはAIに聞いたらすぐ答えが出そうな感じが。
738デフォルトの名無しさん
2025/04/08(火) 23:28:40.30ID:OzdBhfzQ >>712 Rust
fn solve(n: usize, limit: usize) -> Vec<usize> {
let mut answer = Vec::new();
let mut pnt = generate_primes(n).iter().skip(1).rev().map(|&p| (p, 0, 0)).collect::<Vec<_>>();
let (mut ci, mut cn, mut ct) = (0, n, 1_usize);
'advance: loop {
pnt[ci..].iter_mut().for_each(|(_p, n, t)| (*n, *t) = (cn, ct));
if cn & 1 == 0 && ct.leading_zeros() >= (cn >> 1) as u32 {
ct <<= cn >> 1;
if ct <= limit { answer.push(ct as usize); }
}
for (i, (p, n, t)) in pnt.iter_mut().enumerate().rev() {
if *n < *p { continue; }
*n -= *p; *t *= *p;
if *t > limit { continue; }
if *n == 1 { continue; }
if *n == 0 { answer.push(*t as usize); continue; }
(ci, cn, ct) = (i, *n, *t);
continue 'advance;
};
break;
}
answer.sort(); answer
}
fn solve(n: usize, limit: usize) -> Vec<usize> {
let mut answer = Vec::new();
let mut pnt = generate_primes(n).iter().skip(1).rev().map(|&p| (p, 0, 0)).collect::<Vec<_>>();
let (mut ci, mut cn, mut ct) = (0, n, 1_usize);
'advance: loop {
pnt[ci..].iter_mut().for_each(|(_p, n, t)| (*n, *t) = (cn, ct));
if cn & 1 == 0 && ct.leading_zeros() >= (cn >> 1) as u32 {
ct <<= cn >> 1;
if ct <= limit { answer.push(ct as usize); }
}
for (i, (p, n, t)) in pnt.iter_mut().enumerate().rev() {
if *n < *p { continue; }
*n -= *p; *t *= *p;
if *t > limit { continue; }
if *n == 1 { continue; }
if *n == 0 { answer.push(*t as usize); continue; }
(ci, cn, ct) = (i, *n, *t);
continue 'advance;
};
break;
}
answer.sort(); answer
}
739デフォルトの名無しさん
2025/04/08(火) 23:30:40.48ID:OzdBhfzQ >>738
素因数の総和が2025になる問題を可能な素数の組合せ総当りで挑戦してみました
20億以下で約0.4秒と規定時間以内に実行できました
実行時間 solve(2025, 20000000): 22.638309ms
実行時間 solve(2025, 2000000000): 418.607978ms
fn main() {
for (n, limit) in [(2025, 2000_0000), (2025, 20_0000_0000)] {
let start_time = std::time::Instant::now();
let answer = solve(n, limit);
let end_time = std::time::Instant::now();
println!("実行時間 solve({n}, {limit}): {:?}", end_time - start_time);
// 個数と最初と最後の検証
let (valid_len, valid_first, valid_last) = match (n, limit) {
(2025, 2000_0000) => (1265, 30255, 19970000),
(2025, 20_0000_0000) => (49942, 30255, 1999986740),
_ => (0, 0, 0),
};
assert_eq!(answer.len(), valid_len);
assert_eq!(*answer.first().unwrap(), valid_first);
assert_eq!(*answer.last().unwrap(), valid_last);
}
}
素因数の総和が2025になる問題を可能な素数の組合せ総当りで挑戦してみました
20億以下で約0.4秒と規定時間以内に実行できました
実行時間 solve(2025, 20000000): 22.638309ms
実行時間 solve(2025, 2000000000): 418.607978ms
fn main() {
for (n, limit) in [(2025, 2000_0000), (2025, 20_0000_0000)] {
let start_time = std::time::Instant::now();
let answer = solve(n, limit);
let end_time = std::time::Instant::now();
println!("実行時間 solve({n}, {limit}): {:?}", end_time - start_time);
// 個数と最初と最後の検証
let (valid_len, valid_first, valid_last) = match (n, limit) {
(2025, 2000_0000) => (1265, 30255, 19970000),
(2025, 20_0000_0000) => (49942, 30255, 1999986740),
_ => (0, 0, 0),
};
assert_eq!(answer.len(), valid_len);
assert_eq!(*answer.first().unwrap(), valid_first);
assert_eq!(*answer.last().unwrap(), valid_last);
}
}
740デフォルトの名無しさん
2025/04/09(水) 14:40:43.48ID:jYixYFG8 >>737
AIも同じこと言ってた
AIも同じこと言ってた
741デフォルトの名無しさん
2025/04/09(水) 22:22:33.83ID:Ip5PiQSs >>738-739
出題時に作成した解答例
C++
https://ideone.com/y1YZlj
R
https://ideone.com/zvqAsg
と解の個数と最小値・最大値が一致するので正解だろう。
ローカルでコンパイルしようとしたら、
error[E0425]: cannot find function `generate_primes` in this scope
と表示されコンパイルできなかったので、実行時間の比較はできなかった。
出題時に作成した解答例
C++
https://ideone.com/y1YZlj
R
https://ideone.com/zvqAsg
と解の個数と最小値・最大値が一致するので正解だろう。
ローカルでコンパイルしようとしたら、
error[E0425]: cannot find function `generate_primes` in this scope
と表示されコンパイルできなかったので、実行時間の比較はできなかった。
742デフォルトの名無しさん
2025/04/09(水) 22:57:11.84ID:R3DmBa+t >>741
すみません
素数の一覧を返すだけなので素数列挙でもライブラリ利用でも何でもいいのですが
例えばエラトステネスの篩ならこんな感じの関数で
// 素数の一覧を返す [2, 3, 5, 7, 11, ... , (最大max)]
fn generate_primes(max: usize) -> Vec<usize> {
// maxの平方根までの素数の倍数を篩にかければ全ての素数が見つかる
let limit = max.isqrt() + 1;
let mut is_prime = vec![true; max + 1];
is_prime[0] = false;
is_prime[1] = false;
// 偽初期値
let mut prime = 1;
// 次の素数を探す (前回の素数以降でtrueを探すと次の素数)
while let Some(pos) = is_prime[(prime + 1)..limit].iter().position(|bool| *bool) {
prime += pos + 1;
// この素数の倍数をfalseにする 【エラトステネスの篩】
is_prime[(prime << 1)..].iter_mut().step_by(prime).for_each(|bool| *bool = false);
}
// 素数一覧を返す (trueになるindex値が素数)
is_prime.iter().enumerate().filter_map(|(index, bool)| bool.then_some(index)).collect()
}
すみません
素数の一覧を返すだけなので素数列挙でもライブラリ利用でも何でもいいのですが
例えばエラトステネスの篩ならこんな感じの関数で
// 素数の一覧を返す [2, 3, 5, 7, 11, ... , (最大max)]
fn generate_primes(max: usize) -> Vec<usize> {
// maxの平方根までの素数の倍数を篩にかければ全ての素数が見つかる
let limit = max.isqrt() + 1;
let mut is_prime = vec![true; max + 1];
is_prime[0] = false;
is_prime[1] = false;
// 偽初期値
let mut prime = 1;
// 次の素数を探す (前回の素数以降でtrueを探すと次の素数)
while let Some(pos) = is_prime[(prime + 1)..limit].iter().position(|bool| *bool) {
prime += pos + 1;
// この素数の倍数をfalseにする 【エラトステネスの篩】
is_prime[(prime << 1)..].iter_mut().step_by(prime).for_each(|bool| *bool = false);
}
// 素数一覧を返す (trueになるindex値が素数)
is_prime.iter().enumerate().filter_map(|(index, bool)| bool.then_some(index)).collect()
}
743デフォルトの名無しさん
2025/04/09(水) 23:40:58.68ID:Ip5PiQSs744デフォルトの名無しさん
2025/04/09(水) 23:43:56.02ID:R3DmBa+t 前者はどっち?
アルゴリズムが違うのかちょっと見てみる
アルゴリズムが違うのかちょっと見てみる
745デフォルトの名無しさん
2025/04/09(水) 23:50:45.01ID:Ip5PiQSs746デフォルトの名無しさん
2025/04/09(水) 23:59:16.31ID:R3DmBa+t たしかにC++の20億だと数秒かかりますね
何がそんなに違うのかな
何がそんなに違うのかな
747デフォルトの名無しさん
2025/04/10(木) 00:43:03.90ID:1pFQYAQA vectorのメモリは必要分を最初に確保すると速くならない?
vectorの最初のサイズの初期値は要素10個分だったはず。11個目が追加されたら20個確保して全要素コピーんsんてやってたら遅いよ
vectorの最初のサイズの初期値は要素10個分だったはず。11個目が追加されたら20個確保して全要素コピーんsんてやってたら遅いよ
748デフォルトの名無しさん
2025/04/10(木) 02:19:18.58ID:Zvxe3V8x ベクタはC++もRustも他でもほぼ同じ仕様で埋まると倍の新たなエリアを確保してコピー
これは2^n個が埋まった時点でそれ以前の累積コピー個数は
最悪の1個スタートでも1+2+4+ ... + 2^(n-2)+2^(n-1) =2^n - 1個しかない
つまりO(1)とみなせるため問題になることは少ない
言語による詳細な差もC++とRustならほぼ無いと思われる
一方で今回の20億以内で素数和が2025になる数を求める問題
C++版がRust版より約10倍遅くなってる原因は
・pushしていくベクタがRust版は1個でC++版は2026個のベクタを利用
・pushしていく回数がRust版は解の個数と同じ49942回でC++版は134621081回
ワーキングメモリ使用量の差が効いてる
これは2^n個が埋まった時点でそれ以前の累積コピー個数は
最悪の1個スタートでも1+2+4+ ... + 2^(n-2)+2^(n-1) =2^n - 1個しかない
つまりO(1)とみなせるため問題になることは少ない
言語による詳細な差もC++とRustならほぼ無いと思われる
一方で今回の20億以内で素数和が2025になる数を求める問題
C++版がRust版より約10倍遅くなってる原因は
・pushしていくベクタがRust版は1個でC++版は2026個のベクタを利用
・pushしていく回数がRust版は解の個数と同じ49942回でC++版は134621081回
ワーキングメモリ使用量の差が効いてる
749デフォルトの名無しさん
2025/04/10(木) 22:03:03.91ID:Y2N8/SQw >>747
vector p[0]〜p[S]のサイズの最大値4499個(20億以下では88876個)分のメモリを
for (auto &v : p) v.reserve(4499);
で最初に割り付けておくと、>>743ではRustの方が2000万以下で27%、20億以下で11%速かったのが、
2000万以下では差が縮まりRustの方が14%速く、20億以下では逆転しRustの方が20%遅くなった。
サイズの最大値は実行前には分からないから、上記の改変はあくまでもvectorのサイズ拡張が実行時間に
及ぼす影響を見るためのテストで、解答として使うことはできないが。
vectorのサイズ拡張は、新しいメモリ割り付けとそこへの要素コピーに掛かる時間によってだけではなく、
要素の格納アドレスが変わることによるキャッシュ有効率の低下によっても、速度低下をもたらしそう。
>>746, 748
どっちがどれだけ速いかは実行環境に依存するとはいえ、C++が20億で数秒とかRustより約10倍遅いと
いうのはいくら何でも遅すぎておかしいと思う。解の標準出力をなしにするのを忘れていたり、Windowsで
コンパイル後の実行ファイルの実行時間をPowerShellでmeasure-command {a.exe}のように計測して
ウィルス・チェックに要した時間も含まれていたりしない?
vector p[0]〜p[S]のサイズの最大値4499個(20億以下では88876個)分のメモリを
for (auto &v : p) v.reserve(4499);
で最初に割り付けておくと、>>743ではRustの方が2000万以下で27%、20億以下で11%速かったのが、
2000万以下では差が縮まりRustの方が14%速く、20億以下では逆転しRustの方が20%遅くなった。
サイズの最大値は実行前には分からないから、上記の改変はあくまでもvectorのサイズ拡張が実行時間に
及ぼす影響を見るためのテストで、解答として使うことはできないが。
vectorのサイズ拡張は、新しいメモリ割り付けとそこへの要素コピーに掛かる時間によってだけではなく、
要素の格納アドレスが変わることによるキャッシュ有効率の低下によっても、速度低下をもたらしそう。
>>746, 748
どっちがどれだけ速いかは実行環境に依存するとはいえ、C++が20億で数秒とかRustより約10倍遅いと
いうのはいくら何でも遅すぎておかしいと思う。解の標準出力をなしにするのを忘れていたり、Windowsで
コンパイル後の実行ファイルの実行時間をPowerShellでmeasure-command {a.exe}のように計測して
ウィルス・チェックに要した時間も含まれていたりしない?
750デフォルトの名無しさん
2025/04/11(金) 07:38:20.09ID:oaeJuxMT >>738 に手を加えて10倍速くしてみた
fn solve(n: usize, limit: usize) -> Vec<usize> {
let mut answer = Vec::new();
let mut pnt = generate_primes(n).windows(2).rev().map(|s| (s[1], s[0], 0, 0)).collect::<Vec<_>>();
let (mut ci, mut cn, mut ct) = (0, n, 1_usize);
'advance: loop {
pnt[ci..].iter_mut().for_each(|(_p, _q, n, t)| (*n, *t) = (cn, ct));
if cn & 1 == 0 && ct.leading_zeros() >= (cn >> 1) as u32 {
ct <<= cn >> 1; if ct <= limit { answer.push(ct); }
}
'back: for (i, (p, q, n, t)) in pnt.iter_mut().enumerate().rev() {
'again: loop {
if *n < *p { continue 'back; }
*n -= *p; *t *= *p;
if *n ==1 || *t > limit { continue 'back; }
if *n == 0 { answer.push(*t); continue 'back; }
if *q > 3 {
let mut tt = *t * (*n % *q);
for _ in 0..(*n / *q) { tt *= *q; if tt > limit { continue 'again; } }
}; break 'again;
}; (ci, cn, ct) = (i, *n, *t); continue 'advance;
}; break 'advance;
}; answer.sort(); answer
}
fn solve(n: usize, limit: usize) -> Vec<usize> {
let mut answer = Vec::new();
let mut pnt = generate_primes(n).windows(2).rev().map(|s| (s[1], s[0], 0, 0)).collect::<Vec<_>>();
let (mut ci, mut cn, mut ct) = (0, n, 1_usize);
'advance: loop {
pnt[ci..].iter_mut().for_each(|(_p, _q, n, t)| (*n, *t) = (cn, ct));
if cn & 1 == 0 && ct.leading_zeros() >= (cn >> 1) as u32 {
ct <<= cn >> 1; if ct <= limit { answer.push(ct); }
}
'back: for (i, (p, q, n, t)) in pnt.iter_mut().enumerate().rev() {
'again: loop {
if *n < *p { continue 'back; }
*n -= *p; *t *= *p;
if *n ==1 || *t > limit { continue 'back; }
if *n == 0 { answer.push(*t); continue 'back; }
if *q > 3 {
let mut tt = *t * (*n % *q);
for _ in 0..(*n / *q) { tt *= *q; if tt > limit { continue 'again; } }
}; break 'again;
}; (ci, cn, ct) = (i, *n, *t); continue 'advance;
}; break 'advance;
}; answer.sort(); answer
}
751デフォルトの名無しさん
2025/04/11(金) 22:07:48.99ID:CMM29JI3 すごいな
アルゴリズムの違いでそんなに速度差変わるものなんだな
アルゴリズムの違いでそんなに速度差変わるものなんだな
752デフォルトの名無しさん
2025/04/11(金) 22:44:47.89ID:4wK2/GRg753デフォルトの名無しさん
2025/04/12(土) 09:11:24.51ID:xiQsTIG2754デフォルトの名無しさん
2025/04/12(土) 21:18:53.69ID:RVQAocGC >>741のC++プログラムは for (int i = S; i >= 2; i--) のループの最後のi = 2の場合を
ループの外に出して最適化 (p[S]以外のp[_]への要素追加をしないように) するだけで、
20億以下で解の出力なしのときの実行時間が元のプログラムの半分未満になるな。
https://ideone.com/RtTEO2 (1.02秒)
↓
https://ideone.com/1O04wl (0.44秒)
ループの外に出して最適化 (p[S]以外のp[_]への要素追加をしないように) するだけで、
20億以下で解の出力なしのときの実行時間が元のプログラムの半分未満になるな。
https://ideone.com/RtTEO2 (1.02秒)
↓
https://ideone.com/1O04wl (0.44秒)
755デフォルトの名無しさん
2025/04/12(土) 21:26:41.27ID:csJOBVaF756753
2025/04/13(日) 11:09:12.37ID:vq5HB/06757デフォルトの名無しさん
2025/04/13(日) 23:46:14.76ID:bmEZDV0H >>756
遅い原因は長さ2000万のベクタ利用?
遅い原因は長さ2000万のベクタ利用?
758デフォルトの名無しさん
2025/04/13(日) 23:53:41.46ID:fz+Jdq57 配列にするとどうかね
759デフォルトの名無しさん
2025/04/17(木) 00:27:46.72ID:dz0qzhSq 素因数和2025のお題の3系統のコードを読み解いてみた
>>756
2000万まで各々で素因数の和を求めて2025になるかを確認する方法。
ただし各数の素因数分解を工夫せずにすると大変なので、
各数の最小素因数(SPF)を先に一気にエラトステネスの篩で求めてる。
それを用いれば各数の素因数分解はその分解数回の割算だけで求まる。
ただしそのSPF表のために長さ2000万のベクタを用いている。
もし20億までなら32bit✕20億で8GBが許容できるとしても、
あるいはこのSPF一覧のベクタを用いなくても、
20億回の処理を劇的に減らす枝刈り方法を組み込めないと厳しい。
2000万までの計算でも一番遅い。
>>756
2000万まで各々で素因数の和を求めて2025になるかを確認する方法。
ただし各数の素因数分解を工夫せずにすると大変なので、
各数の最小素因数(SPF)を先に一気にエラトステネスの篩で求めてる。
それを用いれば各数の素因数分解はその分解数回の割算だけで求まる。
ただしそのSPF表のために長さ2000万のベクタを用いている。
もし20億までなら32bit✕20億で8GBが許容できるとしても、
あるいはこのSPF一覧のベクタを用いなくても、
20億回の処理を劇的に減らす枝刈り方法を組み込めないと厳しい。
2000万までの計算でも一番遅い。
760デフォルトの名無しさん
2025/04/17(木) 00:29:06.02ID:dz0qzhSq >>741
2000万個すべてを素因数分解する方法とは逆に、
2025以下の素数の組み合わせを調べていく方法。
そのうち和が2025になる組み合わせの積が各解となる。
それを効率よく求めるために2025(+1)個のベクタのベクタpを用意している。
つまり和がsumとなる時の積をp[sum]に記録していく。
効率面からの仮の初期値p[0]に1を入れて、各素数iについて降順に、
ベクタp[j]にxがある時、ベクタp[i+j]にx*iをpushしていく。
ここでjの上限は 2025 - i、処理するxの上限は 2000万 / i の枝刈りができる。
最終的にベクタp[2025]の一覧が解となる。
2025個のベクタを用いることが長所および短所になっている。
この改良版>>754では、最後の素数2だけ特別扱いすることで倍速にしている。
2000万個すべてを素因数分解する方法とは逆に、
2025以下の素数の組み合わせを調べていく方法。
そのうち和が2025になる組み合わせの積が各解となる。
それを効率よく求めるために2025(+1)個のベクタのベクタpを用意している。
つまり和がsumとなる時の積をp[sum]に記録していく。
効率面からの仮の初期値p[0]に1を入れて、各素数iについて降順に、
ベクタp[j]にxがある時、ベクタp[i+j]にx*iをpushしていく。
ここでjの上限は 2025 - i、処理するxの上限は 2000万 / i の枝刈りができる。
最終的にベクタp[2025]の一覧が解となる。
2025個のベクタを用いることが長所および短所になっている。
この改良版>>754では、最後の素数2だけ特別扱いすることで倍速にしている。
761デフォルトの名無しさん
2025/04/17(木) 00:32:14.51ID:dz0qzhSq >>738
これも2025以下の素数を組み合わせて和が2025になる解を調べる方法。
解一覧を収めるベクタ以外は、固定の長さ305のベクタのみが使われている。
この長さの 305 とは2025以下~3以上の素数[2017, 2011, ... 5, 3]の数になってる。
各素数の冪乗の和 2017^e2017 + 2011^e2011 + ... + 5^e5 + 3^e3 及び積を計算していくが、
各指数のe2017などは解に不要なので使われておらず、
各冪乗の和自体も不要なので2025までの残りの数が使われていて、
固定長ベクタの値は(素数, 残りの数, ここまでの積)の3つ組となっている。
その素数を1つ使うと残りの数が減算されてて積が乗算されるのを繰り返していく。
素数2だけ特別扱いされており、残りの数の半分だけ左シフトすると解の積が出来上がる。
各if~continueが枝刈りとなっていて、残りの下限(=和の上限)や積の上限などがある
この改良版>>750では、次の素数以降の組み合わせで起き得る積の下限で枝刈りしている。
例えば7以下の素数で残り21ならば積の下限は7*7*7=343となるため、
ここまでの積に343を掛けた値が2000万(または20億)を超えていれば枝刈りできるようだ。
このアルゴリズムは作業メモリが固定で小さく常にL1キャッシュに乗り有利と思われる点と、
様々な枝刈りがしやすく処理する組み合わせを大きく減らしている点により、
他のアルゴリズムより桁違いに高速になっていると推測される。
これも2025以下の素数を組み合わせて和が2025になる解を調べる方法。
解一覧を収めるベクタ以外は、固定の長さ305のベクタのみが使われている。
この長さの 305 とは2025以下~3以上の素数[2017, 2011, ... 5, 3]の数になってる。
各素数の冪乗の和 2017^e2017 + 2011^e2011 + ... + 5^e5 + 3^e3 及び積を計算していくが、
各指数のe2017などは解に不要なので使われておらず、
各冪乗の和自体も不要なので2025までの残りの数が使われていて、
固定長ベクタの値は(素数, 残りの数, ここまでの積)の3つ組となっている。
その素数を1つ使うと残りの数が減算されてて積が乗算されるのを繰り返していく。
素数2だけ特別扱いされており、残りの数の半分だけ左シフトすると解の積が出来上がる。
各if~continueが枝刈りとなっていて、残りの下限(=和の上限)や積の上限などがある
この改良版>>750では、次の素数以降の組み合わせで起き得る積の下限で枝刈りしている。
例えば7以下の素数で残り21ならば積の下限は7*7*7=343となるため、
ここまでの積に343を掛けた値が2000万(または20億)を超えていれば枝刈りできるようだ。
このアルゴリズムは作業メモリが固定で小さく常にL1キャッシュに乗り有利と思われる点と、
様々な枝刈りがしやすく処理する組み合わせを大きく減らしている点により、
他のアルゴリズムより桁違いに高速になっていると推測される。
762デフォルトの名無しさん
2025/05/03(土) 06:56:07.77ID:Hs+w1scb お題:0か1のランダムな要素を持つW*Hの行列と二点の座標x, yとp, qが入力される
直線(x,y)→(p, q) を行列内で要素1に当たらないように任意の位置に合同変換したい
合同変換できる座標があればその二点の座標を出力し、なければ「なし」と出力せよ
直線(x,y)→(p, q) を行列内で要素1に当たらないように任意の位置に合同変換したい
合同変換できる座標があればその二点の座標を出力し、なければ「なし」と出力せよ
763デフォルトの名無しさん
2025/05/03(土) 14:00:53.01ID:2KurydQy ?
764デフォルトの名無しさん
2025/05/03(土) 14:59:51.97ID:LoSO6jC9 行列の1は格子点上の印なのかクロスワードの黒マスなのか
(x,y)、(p,q)は任意の点なのか格子点なのか
合同変換される直線(x,y)→(p,q)は実は線分だったりしないのか
無限の可能性を感じさせるお題だな
(x,y)、(p,q)は任意の点なのか格子点なのか
合同変換される直線(x,y)→(p,q)は実は線分だったりしないのか
無限の可能性を感じさせるお題だな
765デフォルトの名無しさん
2025/05/03(土) 15:10:32.79ID:OINldK7L 検証用のデータを書いていないお題は失格
入力例とその時の出力例が必要
もし出力が複数個で長いならその特例の一部や個数など
入力例とその時の出力例が必要
もし出力が複数個で長いならその特例の一部や個数など
766デフォルトの名無しさん
2025/06/21(土) 16:41:25.25ID:muNvYhtO お題
2次元の配列があったときに
一番左上を起点として右上方向、左下方向、右上方向…
というふうに斜めに配列の要素をたどることを
ジグザグスキャンと名付けます
たとえば、3 * 3の配列の場合は次の順番で配列の要素にアクセスします
(1, 2, 6)
(3, 5, 7)
(4, 8, 9)
二次元の配列を入力としてジグザグスキャンを行ってください
結果を1次元の配列として出力してください
例
入力: (A, B, C), (D, E, F), (G, H, I)
出力: (A, B, D, G, E, C, F, H, I)
入力: (A, B, C), (D, E, F)
出力: (A, B, D, E, C, F)
入力: (A, B), (C, D), (E, F)
出力: (A, B, C, E, D, F)
2次元の配列があったときに
一番左上を起点として右上方向、左下方向、右上方向…
というふうに斜めに配列の要素をたどることを
ジグザグスキャンと名付けます
たとえば、3 * 3の配列の場合は次の順番で配列の要素にアクセスします
(1, 2, 6)
(3, 5, 7)
(4, 8, 9)
二次元の配列を入力としてジグザグスキャンを行ってください
結果を1次元の配列として出力してください
例
入力: (A, B, C), (D, E, F), (G, H, I)
出力: (A, B, D, G, E, C, F, H, I)
入力: (A, B, C), (D, E, F)
出力: (A, B, D, E, C, F)
入力: (A, B), (C, D), (E, F)
出力: (A, B, C, E, D, F)
767デフォルトの名無しさん
2025/06/21(土) 19:44:57.30ID:jAwJC0YX768デフォルトの名無しさん
2025/06/21(土) 23:05:10.33ID:awm9eire >>766
Rust
fn f<T: Clone, const M: usize, const N: usize>(input: &[[T; N]; M]) -> Vec<T> {
let mut output = Vec::<T>::new();
for x in 0..(M + N - 1) {
let start = if x < N { 0 } else { x + 1 - N };
let end = if x < M { x } else { M - 1 };
let iter = (start..=end).map(|m| input[m][x - m].clone());
if x & 1 == 1 {
output.extend(iter.clone());
} else {
output.extend(iter.rev());
}
}
output
}
fn main() {
assert_eq!(f(&[['A', 'B', 'C'], ['D', 'E', 'F'], ['G', 'H', 'I']]), ['A', 'B', 'D', 'G', 'E', 'C', 'F', 'H', 'I']);
assert_eq!(f(&[['A', 'B', 'C'], ['D', 'E', 'F']]), ['A', 'B', 'D', 'E', 'C', 'F']);
assert_eq!(f(&[['A', 'B'], ['C', 'D'], ['E', 'F']]), ['A', 'B', 'C', 'E', 'D', 'F']);
}
Rust
fn f<T: Clone, const M: usize, const N: usize>(input: &[[T; N]; M]) -> Vec<T> {
let mut output = Vec::<T>::new();
for x in 0..(M + N - 1) {
let start = if x < N { 0 } else { x + 1 - N };
let end = if x < M { x } else { M - 1 };
let iter = (start..=end).map(|m| input[m][x - m].clone());
if x & 1 == 1 {
output.extend(iter.clone());
} else {
output.extend(iter.rev());
}
}
output
}
fn main() {
assert_eq!(f(&[['A', 'B', 'C'], ['D', 'E', 'F'], ['G', 'H', 'I']]), ['A', 'B', 'D', 'G', 'E', 'C', 'F', 'H', 'I']);
assert_eq!(f(&[['A', 'B', 'C'], ['D', 'E', 'F']]), ['A', 'B', 'D', 'E', 'C', 'F']);
assert_eq!(f(&[['A', 'B'], ['C', 'D'], ['E', 'F']]), ['A', 'B', 'C', 'E', 'D', 'F']);
}
769デフォルトの名無しさん
2025/06/29(日) 20:45:32.73ID:f7vmTtNq お題:W*Hの行列に迷路を生成してください(アルゴリズムは任意)
770デフォルトの名無しさん
2025/06/29(日) 21:58:43.69ID:HlaloW8+771デフォルトの名無しさん
2025/07/25(金) 12:30:11.02ID:CjDQVF2B 【問題】
整数のリストが与えられたとき、そのリストを昇順に安定ソートした時の各要素のインデクス(0開始)を対応させたリストを作成せよ
【例】
入力: 1 100 10 10000 1000
出力: 0 2 1 4 3
入力: 3 1 4 1 5 9 2
出力: 3 0 4 1 5 6 2
入力: 0 1 0 1 0 1 0 1
出力: 0 4 1 5 2 6 3 7
実際に必要になって実装したけどスマートな方法があったら知りたい
整数のリストが与えられたとき、そのリストを昇順に安定ソートした時の各要素のインデクス(0開始)を対応させたリストを作成せよ
【例】
入力: 1 100 10 10000 1000
出力: 0 2 1 4 3
入力: 3 1 4 1 5 9 2
出力: 3 0 4 1 5 6 2
入力: 0 1 0 1 0 1 0 1
出力: 0 4 1 5 2 6 3 7
実際に必要になって実装したけどスマートな方法があったら知りたい
772デフォルトの名無しさん
2025/07/25(金) 20:46:23.28ID:dyl0C+2U >>771
例がおかしい
わかりやすい最後の例で示すと
入力: 0 1 0 1 0 1 0 1
出力: 0 4 1 5 2 6 3 7 間違い
出力: 0 2 4 6 1 3 5 7 正解
安定ソートなので同値は順序を保ってこうなる
例がおかしい
わかりやすい最後の例で示すと
入力: 0 1 0 1 0 1 0 1
出力: 0 4 1 5 2 6 3 7 間違い
出力: 0 2 4 6 1 3 5 7 正解
安定ソートなので同値は順序を保ってこうなる
773デフォルトの名無しさん
2025/07/25(金) 21:30:28.86ID:Z69qH9vG774デフォルトの名無しさん
2025/07/26(土) 12:26:55.07ID:xCVVpUlx775デフォルトの名無しさん
2025/07/26(土) 15:08:13.56ID:T78ZrTu7 >>771
SQL
select
row_number() over(order by arrayValue, arrayIndex) - 1
from
arrayTable
order by
arrayIndex
SQL
select
row_number() over(order by arrayValue, arrayIndex) - 1
from
arrayTable
order by
arrayIndex
776デフォルトの名無しさん
2025/07/26(土) 19:25:22.74ID:T78ZrTu7777デフォルトの名無しさん
2025/07/27(日) 10:09:36.80ID:vFJ24xnO >>771 ocaml
https://ideone.com/E7eFPC
>>771 octave
https://ideone.com/KkHu9S
>>771 ruby
https://ideone.com/pPIxcE
https://ideone.com/E7eFPC
>>771 octave
https://ideone.com/KkHu9S
>>771 ruby
https://ideone.com/pPIxcE
778デフォルトの名無しさん
2025/07/27(日) 17:05:48.29ID:vFJ24xnO779デフォルトの名無しさん
2025/07/27(日) 17:08:58.25ID:vFJ24xnO >>771 ruby 2.6以降?
sorti = ->a {a.map.with_index.sort.map &:last}
f = sorti << sorti
g = method(:p) << f
sorti = ->a {a.map.with_index.sort.map &:last}
f = sorti << sorti
g = method(:p) << f
780デフォルトの名無しさん
2025/07/27(日) 20:19:17.79ID:uFbo+/2v >>771
R
https://ideone.com/ctaQC5
統計用言語だけあってライブラリ関数rankを呼び出すだけ。ties.method = "min"を指定すれば
同値を同順位(例えば2番目の例では出力が3 0 4 0 5 6 2となる)にもできる。
R
https://ideone.com/ctaQC5
統計用言語だけあってライブラリ関数rankを呼び出すだけ。ties.method = "min"を指定すれば
同値を同順位(例えば2番目の例では出力が3 0 4 0 5 6 2となる)にもできる。
781デフォルトの名無しさん
2025/07/27(日) 21:43:59.43ID:w39E9j9Q >>771
Rust
既に色々と出ているため別の観点からのコード
一時作業メモリ最小 & ソートは1回 & ジェネリック
fn f<T: std::cmp::Ord>(input: &[T]) -> Vec<usize> {
let len = input.len();
// ポジションのリスト [0, 1, 2, 3, ... , len-1] を作成
let mut pos_list: Vec<usize> = (0..len).collect();
// inputを利用してそのポジションだけをソート
pos_list.sort_by_key(|&pos| &input[pos]);
// 返すべきランクのリスト
let mut rank_list: Vec<usize> = vec![0; len];
// ポジション⇔ランクは逆写像なのでソートは不要
(0..len).for_each(|rank| rank_list[pos_list[rank]] = rank);
rank_list
}
fn main() {
assert_eq!(f(&[1, 100, 10, 10000, 1000]), [0, 2, 1, 4, 3]);
assert_eq!(f(&[3, 1, 4, 1, 5, 9, 2]), [3, 0, 4, 1, 5, 6, 2]);
assert_eq!(f(&[0, 1, 0, 1, 0, 1, 0, 1]), [0, 4, 1, 5, 2, 6, 3, 7]);
}
Rust
既に色々と出ているため別の観点からのコード
一時作業メモリ最小 & ソートは1回 & ジェネリック
fn f<T: std::cmp::Ord>(input: &[T]) -> Vec<usize> {
let len = input.len();
// ポジションのリスト [0, 1, 2, 3, ... , len-1] を作成
let mut pos_list: Vec<usize> = (0..len).collect();
// inputを利用してそのポジションだけをソート
pos_list.sort_by_key(|&pos| &input[pos]);
// 返すべきランクのリスト
let mut rank_list: Vec<usize> = vec![0; len];
// ポジション⇔ランクは逆写像なのでソートは不要
(0..len).for_each(|rank| rank_list[pos_list[rank]] = rank);
rank_list
}
fn main() {
assert_eq!(f(&[1, 100, 10, 10000, 1000]), [0, 2, 1, 4, 3]);
assert_eq!(f(&[3, 1, 4, 1, 5, 9, 2]), [3, 0, 4, 1, 5, 6, 2]);
assert_eq!(f(&[0, 1, 0, 1, 0, 1, 0, 1]), [0, 4, 1, 5, 2, 6, 3, 7]);
}
782777
2025/07/27(日) 22:54:22.66ID:YfUjoiLt783 警備員[Lv.11]
2025/07/28(月) 23:30:37.16ID:uO5vEij8 >>771
>>776をKotlinに変換してKotlinらしくなるように色々省略しただけのもの。
やはり最初からラムダとか考慮されている言語だと色々省略できて分り易くなるね。
https://paiza.io/projects/0Dhknk4mUHrMqtuwzCDAxQ
>>776をKotlinに変換してKotlinらしくなるように色々省略しただけのもの。
やはり最初からラムダとか考慮されている言語だと色々省略できて分り易くなるね。
https://paiza.io/projects/0Dhknk4mUHrMqtuwzCDAxQ
784デフォルトの名無しさん
2025/07/29(火) 00:12:31.56ID:9AXsNEm+ >>771
Rust
https://ideone.com/jYX2ws
バイナリヒープ使うとソート過程で直接リスト作れるけどコード量増えるしヒープソート遅いから実用性は微妙か
C言語ならありかもしれない
Rust
https://ideone.com/jYX2ws
バイナリヒープ使うとソート過程で直接リスト作れるけどコード量増えるしヒープソート遅いから実用性は微妙か
C言語ならありかもしれない
785デフォルトの名無しさん
2025/07/30(水) 21:50:10.50ID:Ug40aZKP786デフォルトの名無しさん
2025/07/31(木) 14:56:29.97ID:cLL+G38O >> 771
java
>> 785氏のデータも加えてみた。
https://ideone.com/vzXoGd
ideoneのjavaはバージョン古いのか...
ま、通りがかりにこのスレみつけたのでちょっと書いただけ。
java
>> 785氏のデータも加えてみた。
https://ideone.com/vzXoGd
ideoneのjavaはバージョン古いのか...
ま、通りがかりにこのスレみつけたのでちょっと書いただけ。
787デフォルトの名無しさん
2025/07/31(木) 18:54:11.86ID:cLL+G38O ち、勘が鈍った。>>もつけ間違えるし、sage忘れるし。
788785
2025/07/31(木) 21:15:09.63ID:R3hgrYP8789デフォルトの名無しさん
2025/08/03(日) 22:00:37.87ID:1jv9m6G7790デフォルトの名無しさん
2025/08/04(月) 22:42:57.64ID:A9zbJQ8U791デフォルトの名無しさん
2025/08/04(月) 23:09:28.79ID:A9zbJQ8U792デフォルトの名無しさん
2025/08/05(火) 01:04:23.30ID:wgx4FmLX class ValueWithIndex<U /*extends Comparable<U>*/> implements Comparable<ValueWithIndex<T>> {
ジェネリックは難しい。上のextends Comparable<U>は無くてもよいのだが、無駄でも明記したほうがよさそうなので、
ソースではそうした。
明記しなくとも、Uは正しく推測されているようだ。
ジェネリックは難しい。上のextends Comparable<U>は無くてもよいのだが、無駄でも明記したほうがよさそうなので、
ソースではそうした。
明記しなくとも、Uは正しく推測されているようだ。
793デフォルトの名無しさん
2025/08/06(水) 17:17:53.29ID:qE4NV2ND794デフォルトの名無しさん
2025/08/07(木) 07:21:55.28ID:W/yAWgo4 これからはメソッドの時代
795デフォルトの名無しさん
2025/08/10(日) 23:18:32.78ID:FODtZCg5796デフォルトの名無しさん
2025/08/11(月) 20:38:34.09ID:frWpQyFA797デフォルトの名無しさん
2025/08/12(火) 21:05:08.06ID:uRUBTkGF >>771
PowerShell 6以降
function rank($a)
{
$n = $a.length
$r = [int[]]::new($n)
if ($n) {0..($n - 1) | sort-object -stable {$a[$_]} |% {$i = 0} {$r[$_] = $i++}}
$r
}
function PrintArray($a)
{
if ($a.length -le 1) {return $a}
"[$(($a |% {PrintArray $_}) -join ", ")]"
}
$q =
(1, 100, 10, 10000, 1000),
(3, 1, 4, 1, 5, 9, 2),
(0, 1, 0, 1, 0, 1, 0, 1),
@(),
1,
((1, 1), (1, 1), (1, 0, 1), (1, 0))
$q |% {
"入力: $(PrintArray $_)"
"出力: $(PrintArray (rank $_))"
""
}
PowerShell 6以降
function rank($a)
{
$n = $a.length
$r = [int[]]::new($n)
if ($n) {0..($n - 1) | sort-object -stable {$a[$_]} |% {$i = 0} {$r[$_] = $i++}}
$r
}
function PrintArray($a)
{
if ($a.length -le 1) {return $a}
"[$(($a |% {PrintArray $_}) -join ", ")]"
}
$q =
(1, 100, 10, 10000, 1000),
(3, 1, 4, 1, 5, 9, 2),
(0, 1, 0, 1, 0, 1, 0, 1),
@(),
1,
((1, 1), (1, 1), (1, 0, 1), (1, 0))
$q |% {
"入力: $(PrintArray $_)"
"出力: $(PrintArray (rank $_))"
""
}
798デフォルトの名無しさん
2025/08/12(火) 21:05:40.60ID:uRUBTkGF -- 実行結果 --
入力: [1, 100, 10, 10000, 1000]
出力: [0, 2, 1, 4, 3]
入力: [3, 1, 4, 1, 5, 9, 2]
出力: [3, 0, 4, 1, 5, 6, 2]
入力: [0, 1, 0, 1, 0, 1, 0, 1]
出力: [0, 4, 1, 5, 2, 6, 3, 7]
入力:
出力:
入力: 1
出力: 0
入力: [[1, 1], [1, 1], [1, 0, 1], [1, 0]]
出力: [2, 3, 1, 0]
入力: [1, 100, 10, 10000, 1000]
出力: [0, 2, 1, 4, 3]
入力: [3, 1, 4, 1, 5, 9, 2]
出力: [3, 0, 4, 1, 5, 6, 2]
入力: [0, 1, 0, 1, 0, 1, 0, 1]
出力: [0, 4, 1, 5, 2, 6, 3, 7]
入力:
出力:
入力: 1
出力: 0
入力: [[1, 1], [1, 1], [1, 0, 1], [1, 0]]
出力: [2, 3, 1, 0]
799デフォルトの名無しさん
2025/08/16(土) 01:44:59.97ID:VU+jlz0U 【問題A】
1~9を1つずつ使用して表される9桁の数Anは全部で9!(=362880)個存在する。
整数n(1≦n≦362880)が与えられたとき、n番目に小さいAnを求めよ。
(例)
1 → 123456789
2 → 123456798
3 → 123456879
123456 → 416589732
234567 → 684753219
362880 → 987654321
【問題B】
1~4を3つずつ使用して表される12桁の数Bnは全部で12!/(3!)^4(=369600)個存在する。
整数n(1≦n≦369600)が与えられたとき、n番目に小さいBnを求めよ。
(例)
1 → 111222333444
2 → 111222334344
3 → 111222334434
123456 → 222331434114
234567 → 324424331112
369600 → 444333222111
※求める数値は文字列または各桁の数の配列による表現も可能とする(123⇔"123"⇔[1,2,3])
1~9を1つずつ使用して表される9桁の数Anは全部で9!(=362880)個存在する。
整数n(1≦n≦362880)が与えられたとき、n番目に小さいAnを求めよ。
(例)
1 → 123456789
2 → 123456798
3 → 123456879
123456 → 416589732
234567 → 684753219
362880 → 987654321
【問題B】
1~4を3つずつ使用して表される12桁の数Bnは全部で12!/(3!)^4(=369600)個存在する。
整数n(1≦n≦369600)が与えられたとき、n番目に小さいBnを求めよ。
(例)
1 → 111222333444
2 → 111222334344
3 → 111222334434
123456 → 222331434114
234567 → 324424331112
369600 → 444333222111
※求める数値は文字列または各桁の数の配列による表現も可能とする(123⇔"123"⇔[1,2,3])
800デフォルトの名無しさん
2025/08/16(土) 13:16:59.50ID:MUbLd8/3 >>799 Rust 愚直にn回まわし
use itertools::Itertools; // for tuple_windows()
fn f(init: &str, n: usize) -> String {
let mut list = init.chars().rev().collect::<Vec<_>>();
for _ in 1..n {
if let Some((pre_index, (_, old))) = list.iter().tuple_windows().enumerate().find(|(_, (pre, cur))| pre > cur) {
let old_index = pre_index + 1;
let (new_index, _) = list.iter().enumerate().find(|(_, cur)| cur > &old).unwrap();
list.swap(old_index, new_index);
list[..old_index].reverse();
}
}
list.into_iter().rev().collect()
}
fn main() {
assert_eq!(f("123456789", 1), "123456789");
assert_eq!(f("123456789", 2), "123456798");
assert_eq!(f("123456789", 3), "123456879");
assert_eq!(f("123456789", 123456), "416589732");
assert_eq!(f("123456789", 234567), "684753219");
assert_eq!(f("123456789", 362880), "987654321");
assert_eq!(f("111222333444", 1), "111222333444");
assert_eq!(f("111222333444", 2), "111222334344");
assert_eq!(f("111222333444", 3), "111222334434");
assert_eq!(f("111222333444", 123456), "222331434114");
assert_eq!(f("111222333444", 234567), "324424331112");
assert_eq!(f("111222333444", 369600), "444333222111");
}
use itertools::Itertools; // for tuple_windows()
fn f(init: &str, n: usize) -> String {
let mut list = init.chars().rev().collect::<Vec<_>>();
for _ in 1..n {
if let Some((pre_index, (_, old))) = list.iter().tuple_windows().enumerate().find(|(_, (pre, cur))| pre > cur) {
let old_index = pre_index + 1;
let (new_index, _) = list.iter().enumerate().find(|(_, cur)| cur > &old).unwrap();
list.swap(old_index, new_index);
list[..old_index].reverse();
}
}
list.into_iter().rev().collect()
}
fn main() {
assert_eq!(f("123456789", 1), "123456789");
assert_eq!(f("123456789", 2), "123456798");
assert_eq!(f("123456789", 3), "123456879");
assert_eq!(f("123456789", 123456), "416589732");
assert_eq!(f("123456789", 234567), "684753219");
assert_eq!(f("123456789", 362880), "987654321");
assert_eq!(f("111222333444", 1), "111222333444");
assert_eq!(f("111222333444", 2), "111222334344");
assert_eq!(f("111222333444", 3), "111222334434");
assert_eq!(f("111222333444", 123456), "222331434114");
assert_eq!(f("111222333444", 234567), "324424331112");
assert_eq!(f("111222333444", 369600), "444333222111");
}
801デフォルトの名無しさん
2025/08/16(土) 19:14:21.11ID:kN4EEg8M >>799 の問題A
1からnまでの自然数を並べてできるi番目の順列を求める関数を前に作って持っていたので、
それを流用したらすぐできた(元の関数はBigIntとiの範囲外エラーにも対応)。
R
https://ideone.com/hMTf2k
C++
https://ideone.com/ZiU5Aa
1からnまでの自然数を並べてできるi番目の順列を求める関数を前に作って持っていたので、
それを流用したらすぐできた(元の関数はBigIntとiの範囲外エラーにも対応)。
R
https://ideone.com/hMTf2k
C++
https://ideone.com/ZiU5Aa
802デフォルトの名無しさん
2025/08/16(土) 20:29:06.33ID:kN4EEg8M803デフォルトの名無しさん
2025/08/16(土) 21:32:58.04ID:kN4EEg8M >>799
>>802 のC++のithDuplicatedPermutation関数は引数が別の値(例えばn = 5, m = 3)のとき
正しく計算できなかったので修正。Rの方はintではなくdoubleで計算しているので問題ない。
https://ideone.com/uH8dpO
>>802 のC++のithDuplicatedPermutation関数は引数が別の値(例えばn = 5, m = 3)のとき
正しく計算できなかったので修正。Rの方はintではなくdoubleで計算しているので問題ない。
https://ideone.com/uH8dpO
804デフォルトの名無しさん
2025/08/16(土) 21:46:08.81ID:VU+jlz0U 32bitだと階乗は12!が限界
805デフォルトの名無しさん
2025/08/17(日) 12:07:33.92ID:R1ye1QDy806805
2025/08/17(日) 15:08:29.44ID:R1ye1QDy807デフォルトの名無しさん
2025/08/17(日) 15:21:28.95ID:OrBxx4uG ソートが消えて>>800と同じアルゴリズムになったね
808デフォルトの名無しさん
2025/08/17(日) 20:40:30.84ID:bUKuWE64 >>804
確かにそうだった。15!も14!もintの範囲内に収まらない。>>803でn = 5に変えた場合に正しい
出力になるのはたまたまだった。
>>802をBigInt化するだけで問題なかった。
R
https://ideone.com/OgBxTJ
C++
https://ideone.com/KLqe3g
確かにそうだった。15!も14!もintの範囲内に収まらない。>>803でn = 5に変えた場合に正しい
出力になるのはたまたまだった。
>>802をBigInt化するだけで問題なかった。
R
https://ideone.com/OgBxTJ
C++
https://ideone.com/KLqe3g
809デフォルトの名無しさん
2025/08/19(火) 21:08:19.27ID:zFi0pntB >>799 問題A
perl
use v5.42;
sub nthPermutation($digits, $rank) {
my @figures = (1..$digits);
my @fact = (1);
push @fact, $_ * $fact[-1] for @figures;
return join "", map { splice(@figures, $_, 1) } sub($n, $r) {
$n-- ? (int($r / $fact[$n]), __SUB__->($n, $r % $fact[$n])) : ();
}->($digits, $rank - 1);
}
for my $i (1, 2, 3, 123456, 234567, 362880) {
say "$i -> " . nthPermutation(9, $i);
}
1 -> 123456789
2 -> 123456798
3 -> 123456879
123456 -> 416589732
234567 -> 684753219
362880 -> 987654321
perl
use v5.42;
sub nthPermutation($digits, $rank) {
my @figures = (1..$digits);
my @fact = (1);
push @fact, $_ * $fact[-1] for @figures;
return join "", map { splice(@figures, $_, 1) } sub($n, $r) {
$n-- ? (int($r / $fact[$n]), __SUB__->($n, $r % $fact[$n])) : ();
}->($digits, $rank - 1);
}
for my $i (1, 2, 3, 123456, 234567, 362880) {
say "$i -> " . nthPermutation(9, $i);
}
1 -> 123456789
2 -> 123456798
3 -> 123456879
123456 -> 416589732
234567 -> 684753219
362880 -> 987654321
810デフォルトの名無しさん
2025/08/19(火) 21:28:38.04ID:ahVErwF8811806
2025/08/21(木) 22:19:54.42ID:fAlkh9Aq812デフォルトの名無しさん
2025/08/21(木) 23:15:48.39ID:0KQ1xtxb >>799 の逆変換プログラム
R
https://ideone.com/TU73Yu
C++
https://ideone.com/dmETd5
問題A, 問題Bとは違って、順列に出現するユニークな整数は1〜nの連番でなくても良いし、
出現回数はすべて同じでなくても良い。例えば、入力は [3, 1, 4, 1, 5, 9] でも良い
(ユニークな整数は1, 3, 4, 5, 9で、出現回数は1が2回、その他が1回)。
R
https://ideone.com/TU73Yu
C++
https://ideone.com/dmETd5
問題A, 問題Bとは違って、順列に出現するユニークな整数は1〜nの連番でなくても良いし、
出現回数はすべて同じでなくても良い。例えば、入力は [3, 1, 4, 1, 5, 9] でも良い
(ユニークな整数は1, 3, 4, 5, 9で、出現回数は1が2回、その他が1回)。
813デフォルトの名無しさん
2025/08/22(金) 01:14:43.39ID:6LYRfbyj814デフォルトの名無しさん
2025/08/22(金) 06:55:21.34ID:qlaiAqZd >>812
Rust >>799の逆変換の重複順列の何番目か算出
use itertools::Itertools;
use num::{BigUint, One};
// 重複順列の何番目かを求める ex. "222331434114" → "123456"番目
fn to_nth(input: &str) -> String {
// 出現数
let (mut counts, chars): (Vec<usize>, Vec<char>) = input.chars().sorted().dedup_with_count().multiunzip();
// index化input
let input: Vec<usize> = input.chars().map(|c| chars.iter().position(|&c0| c0 == c).unwrap()).collect();
// 階乗関数
fn factorial(x: usize) -> BigUint { (1..=x).fold(BigUint::one(), |p, x| p * x) }
// 重複順列の総数
let mut whole: BigUint = factorial(input.len()) / counts.iter().map(|&x| factorial(x)).product::<BigUint>();
// nth番目を算出
(1..=input.len()).rev().zip(input).fold(BigUint::one(), |mut nth, (len, index)| {
// 自分より前までの総数をnthに足す
nth += &whole * counts[..index].iter().sum::<usize>() / len;
// 自分の総数へ更新
whole *= counts[index];
whole /= len;
counts[index] -= 1;
nth
})
.to_string()
}
Rust >>799の逆変換の重複順列の何番目か算出
use itertools::Itertools;
use num::{BigUint, One};
// 重複順列の何番目かを求める ex. "222331434114" → "123456"番目
fn to_nth(input: &str) -> String {
// 出現数
let (mut counts, chars): (Vec<usize>, Vec<char>) = input.chars().sorted().dedup_with_count().multiunzip();
// index化input
let input: Vec<usize> = input.chars().map(|c| chars.iter().position(|&c0| c0 == c).unwrap()).collect();
// 階乗関数
fn factorial(x: usize) -> BigUint { (1..=x).fold(BigUint::one(), |p, x| p * x) }
// 重複順列の総数
let mut whole: BigUint = factorial(input.len()) / counts.iter().map(|&x| factorial(x)).product::<BigUint>();
// nth番目を算出
(1..=input.len()).rev().zip(input).fold(BigUint::one(), |mut nth, (len, index)| {
// 自分より前までの総数をnthに足す
nth += &whole * counts[..index].iter().sum::<usize>() / len;
// 自分の総数へ更新
whole *= counts[index];
whole /= len;
counts[index] -= 1;
nth
})
.to_string()
}
815デフォルトの名無しさん
2025/08/22(金) 06:56:46.07ID:qlaiAqZd >>814の検証分
fn main() {
assert_eq!(to_nth("123456789"), "1");
assert_eq!(to_nth("123456798"), "2");
assert_eq!(to_nth("123456879"), "3");
assert_eq!(to_nth("416589732"), "123456");
assert_eq!(to_nth("684753219"), "234567");
assert_eq!(to_nth("987654321"), "362880");
assert_eq!(to_nth("111222333444"), "1");
assert_eq!(to_nth("111222334344"), "2");
assert_eq!(to_nth("111222334434"), "3");
assert_eq!(to_nth("222331434114"), "123456");
assert_eq!(to_nth("324424331112"), "234567");
assert_eq!(to_nth("444333222111"), "369600");
assert_eq!(to_nth("111333442545225"), "123456");
assert_eq!(to_nth("555444333222111"), "168168000");
assert_eq!(to_nth("11111222223333344444555556666677777899⑩⑩889889⑩⑩⑩9"), "123456");
assert_eq!(to_nth("⑩⑩⑩⑩⑩999998888877777666665555544444333332222211111"), "49120458506088132224064306071170476903628800");
assert_eq!(to_nth("314159"), "127");
assert_eq!(to_nth("3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067"), "11503448027594046007734790817193859678406683579515952737315863863451534425766911708030454269");
assert_eq!(to_nth("なまむぎなまごめなまたまご"), "10515454");
assert_eq!(to_nth("かえるぴょこぴょこみぴょこぴょこあわせてぴょこぴょこむぴょこぴょこ"), "8273693808428448039784");
}
fn main() {
assert_eq!(to_nth("123456789"), "1");
assert_eq!(to_nth("123456798"), "2");
assert_eq!(to_nth("123456879"), "3");
assert_eq!(to_nth("416589732"), "123456");
assert_eq!(to_nth("684753219"), "234567");
assert_eq!(to_nth("987654321"), "362880");
assert_eq!(to_nth("111222333444"), "1");
assert_eq!(to_nth("111222334344"), "2");
assert_eq!(to_nth("111222334434"), "3");
assert_eq!(to_nth("222331434114"), "123456");
assert_eq!(to_nth("324424331112"), "234567");
assert_eq!(to_nth("444333222111"), "369600");
assert_eq!(to_nth("111333442545225"), "123456");
assert_eq!(to_nth("555444333222111"), "168168000");
assert_eq!(to_nth("11111222223333344444555556666677777899⑩⑩889889⑩⑩⑩9"), "123456");
assert_eq!(to_nth("⑩⑩⑩⑩⑩999998888877777666665555544444333332222211111"), "49120458506088132224064306071170476903628800");
assert_eq!(to_nth("314159"), "127");
assert_eq!(to_nth("3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067"), "11503448027594046007734790817193859678406683579515952737315863863451534425766911708030454269");
assert_eq!(to_nth("なまむぎなまごめなまたまご"), "10515454");
assert_eq!(to_nth("かえるぴょこぴょこみぴょこぴょこあわせてぴょこぴょこむぴょこぴょこ"), "8273693808428448039784");
}
816811
2025/08/22(金) 20:26:43.82ID:m9vhyo0Z817816
2025/08/23(土) 20:27:40.18ID:uyhDG+iz818デフォルトの名無しさん
2025/08/23(土) 21:01:55.02ID:gxRFdG35819817
2025/08/23(土) 23:26:24.12ID:uyhDG+izレスを投稿する
ニュース
- 【音楽】Perfume・あ~ちゃんの結婚相手「一般男性」は吉田カバンの社長・吉田幸裕氏(41) 高身長で山本耕史似 [Ailuropoda melanoleuca★]
- 【サッカー】U-17日本代表、激闘PK戦制す 北朝鮮撃破で6大会ぶり8強入り U17W杯 [久太郎★]
- 【サッカー】日本代表、ボリビアに3発快勝 森保監督通算100試合目を飾る…鎌田、町野、中村がゴール [久太郎★]
- 【インバウンド】中国人観光客の日本での消費額は年間約2兆円超…中国政府は公務員の出張取り消し [1ゲットロボ★]
- XやChatGPTで広範囲の通信障害 投稿や閲覧できず [蚤の市★]
- 【芸能】日中関係悪化でエンタメ業界に大ダメージ… JO1の中国でのイベント中止、邦画は公開延期、STARTOアイドルへの影響も [冬月記者★]
- 石井ちゃんです!
- 職場の俺のあだ名がブロリーなんだが
- アンケート調査で「高市発言は問題なし」 93.5%wwwwwwwwwwwwwwwwwwwwwwwww [279254606]
- お前らは“スカイマイルタワー”建設計画を知っているか?
- これ誰か分かるか?
- 万引きJC「すいません許してください!何でもしますから!」←どうする?
