神メソッド
Summer498.icon
ワイの過去に作ったプログラムから$ \argmin,\argmax,\min,\maxの全てを1つのメソッドから呼び出せるようにした神メソッドを発掘した 作ってるときは超楽しいが、保守のときに「あ~、楽しくて作っちゃったのねん……。でもやっぱシンプルな実装のほうがいいわ」ってなる
code:ts
class MaxCalculableArray<T> extends Array<T> {
constructor(...items: T[]) {
super(items.length);
this.#args = this[0, [this0]] items.forEach((_, i) => { thisi = itemsi; }); }
val => val < this.#values0, val => val > this.#values1 ]
this.#valuesis_max = (is_max) ? -Infinity : Infinity; for (const i of this) {
const val = f(i);
if (this.#willRenewis_max(val)) { continue;
}
if (val == this.#valuesis_max) { this.#argsis_max.push(i); } }
}
if (this.#memo_funcsis_max === f) { return; } this.#renew_min_or_max(f, is_max);
}
min(f: (i: T) => number) { this.#checkCache(f, 0); return this.#values0; } argMin(f: (i: T) => number) { this.#checkCache(f, 0); return this.#args00; } argMins(f: (i: T) => number) { this.#checkCache(f, 0); return this.#args0; } max(f: (i: T) => number) { this.#checkCache(f, 1); return this.#values1; } argMax(f: (i: T) => number) { this.#checkCache(f, 1); return this.#args10; } argMaxes(f: (i: T) => number) { this.#checkCache(f, 1); return this.#args1; } }
ここまで来るとコピペのほうが善だわ
普通の配列を一旦 new MaxCalculableArray(...arr); でクラス化しなきゃいけないのが💩ポイント
当時は for ループが嫌いだったからこんな事をしていたな
思想が強い
その時はまっている手法で書いちゃうことよくあるtakker.icon
これがクソゴツいのはクラスになってるせい
code:ts
type: Comparition = (a:number, b:number) => boolean;
const is_lesser: Comparition = (a,b) => a<b;
const is_greater: Comparition = (a,b) => a>b;
const argsMinMax = (f: (i:T) => number, space: T[], compare:Comparition) => {
let val = (compare(0,1)) ? Infinity : -Infinity;
const args: number[] = [];
space.foreach(e => {
const res = f(e);
if(compare(res, val)){
val = res;
}
else if(res===val){ args.push(e); }
})
return {val, args}
}
const min = (f: (i:T) => number, space: T[]) => argsMinMax(f, space, is_lesser).val;
const max = (f: (i:T) => number, space: T[]) => argsMinMax(f, space, is_greater).val;
const argsMin = (f: (i:T) => number, space: T[]) => argsMinMax(f, space, is_lesser).args;
const argsMax = (f: (i:T) => number, space: T[]) => argsMinMax(f, space, is_greater).args;
const argMin = (f: (i:T) => number, space: T[]) => argsMinMax(f, space, is_lesser).args0; const argMax = (f: (i:T) => number, space: T[]) => argsMinMax(f, space, is_greater).args0; なおこのコードのテストはしていない
思い出して手打ちしてるだけ