橋の修理

Dec 22, 2024 am 04:17 AM

Bridge Repair

コード 2024 の出現 7 日目

パート 1

今年最初の再帰

今日は少なくともそうしてゴールドスターを 1 つ獲得するつもりです:

  • 完全なリストから始めます
  • 足し算と掛け算の両方をチェックしてください
  • 各結果について、リストの残りの部分に進みます
  • 合計を超えるか一致するまで

難しいのは細部にあります。

これをやってみよう!

アルゴリズムを作成する

まず、各行を数値のリストに解析する必要があります。

let eqs = input.split('\n').map(line => {
  return [...line.matchAll(/\d+/g)].map(el => +el[0])
})
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

最初の要素は必要な合計です。

残りは方程式の順序付けされたオペランドです。

再帰関数でこれを考慮する必要があります。

これが私の再帰関数です:

function eqChecker(operands, amount, test) {
  if (amount > test) {
    return false
  } else if (amount == test && operands.length == 0) {
    return true
  } else if (operands.length) {
    let copy = operands.slice()
    let first = copy.shift()
    return eqChecker(copy, amount + first, test) || eqChecker(copy, amount * first, test)
  }
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

そして、これを使用するreduceは次のとおりです:

let part1 = eqs.reduce((count, eq) => {
  if (eqChecker(eq.slice(2), eq[1], eq[0])) {
    count += eq[0]
  }
  return count
}, 0)
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

期待していましたが、予想外でした。入力例に対する正しい答えが生成されます。

パズル入力の処理は完了しますか?

もしそうなら、正しい答えが生成されますか?

正直、よくわかりません...

本当にできました!!!

うわー!!!

私はとても興奮していますが、次の部分ではさらに演算子が追加されるか、再帰が実行可能な解決策ではなくなるために高度な CS が必要になるのではないかと心配しています。

パート 2

全く予想外でした!そしてはるかに難しい

どうやってこれを行うのでしょうか?

...

数日後...

私の思考プロセスの要約:

  • 返品条件に 3 番目の条項を追加するのと同じくらい簡単ですか? いいえ
  • パート 1 の再帰関数は成功するように正しく構成されていますか? いいえ
  • ああ、いや、以前の操作の結果として金額を蓄積することは可能でしょうか? いいえ
  • 本当に新しい戦略でこれに取り組む必要があるのでしょうか? そうだね

すべての新しいバリエーションを考慮して

この方程式の場合:

292: 11 6 16 20
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

これらは、3 つの演算子が与えられた場合に考えられるすべての方程式です。

11 
11+6 
11+6+16 
11+6+16+20 
11+6+16*20 
11+6+1620 
11+6*16 
11+6*16+20 
11+6*16*20 
11+6*1620 
11+616 
11*6 
11*6+16 
11*6+16+20 
11*6+16*20 
11*6+1620 
11*6*16 
11*616 
116 
116+16 
116+16+20 
116+16*20 
116+1620 
116*16 
11616 
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

おそらく、各方程式の文字列を構築し、それを再帰関数内で手動で評価できます。

例:
一番外側の関数呼び出しでは空の文字列から始めます:

""
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

そこから、次の番号を使用して 3 つのバリエーションを作成します。

"" + "+N"
"" + "*N"
"" + "N"
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

うーん、でもこれは最初の番号では機能しません。

最初の関数呼び出しを空の文字列ではなく、最初の数値で開始する必要があります:

"N"
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

そこから同じこと:

"N" + "+N"
"N" + "*N"
"N" + "N"
ログイン後にコピー
ログイン後にコピー

ああ、それはうまくいくはずです。

最後までに、これらのサンプル バリエーションが完成し、すべて評価可能になります:

let eqs = input.split('\n').map(line => {
  return [...line.matchAll(/\d+/g)].map(el => +el[0])
})
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

スキップ: コードを作成しました...そしてより大きな問題を発見しました

方程式のすべてのバリエーションを正常に生成するコードを書きました。

function eqChecker(operands, amount, test) {
  if (amount > test) {
    return false
  } else if (amount == test && operands.length == 0) {
    return true
  } else if (operands.length) {
    let copy = operands.slice()
    let first = copy.shift()
    return eqChecker(copy, amount + first, test) || eqChecker(copy, amount * first, test)
  }
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  • 私は数字のリストをたどるのに慣れています
  • 最後の節は、i が最後から 2 番目のインデックスの前またはインデックスにある場合にのみ続行されます

関数は 4 つの値を取得します:

  1. 数値リストのコピーから、予想される合計を差し引いたもの
  2. 次のインデックス
  3. 3 つの文字列のいずれかを連結した方程式文字列
  4. 同じテスト番号

パート 1 とほぼ同じシグネチャを使用して関数を呼び出します。

let part1 = eqs.reduce((count, eq) => {
  if (eqChecker(eq.slice(2), eq[1], eq[0])) {
    count += eq[0]
  }
  return count
}, 0)
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

違いは、引数として渡すものです:

  1. 合計予定額を除いたリスト
  2. インデックス 0 から開始
  3. 最初の数字を含む文字列
  4. 予定総額

素晴らしいニュース:

  • すべての方程式のバリエーションを生成します

悪いニュース:

  • 左から右ではなく、PEMDAS を使用してすべての方程式を評価します

組み込みの JavaScript エバリュエーターはデフォルトで左から右ではなく正しい操作順序を使用することをもっとよく知っておくべきでした。

これは実際に私のアルゴリズムにさらに大きな問題を投げかけます:

  • 各方程式を分解して部分ごとに評価する必要があります

うわー。

ありがたいことに、その方法を知っているようです。

手動で計算する

次のような方程式を評価するには JavaScript を取得する必要があります:

292: 11 6 16 20
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この順序:

11 
11+6 
11+6+16 
11+6+16+20 
11+6+16*20 
11+6+1620 
11+6*16 
11+6*16+20 
11+6*16*20 
11+6*1620 
11+616 
11*6 
11*6+16 
11*6+16+20 
11*6+16*20 
11*6+1620 
11*6*16 
11*616 
116 
116+16 
116+16+20 
116+16*20 
116+1620 
116*16 
11616 
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

その方程式をいくつかの部分に分割したいと思います:

""
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

私がどのように理解する唯一の方法は、この三重連鎖の式を使用することです:

"" + "+N"
"" + "*N"
"" + "N"
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

区切り文字として使用するためだけに、各演算子に空白を埋め込みます。

この方程式部分のリストに関する事実:

  • 常に 3 つ以上の奇数のアイテムが含まれます

各オペランド、演算子、オペランドのペアを反復するループでこの事実を利用するにはどうすればよいですか?

これが私のアイデアです:

  • 最初の 3 つの項目を削除
  • それらを文字列として結合し、それを数式として評価します
  • 結果を方程式リストの先頭に再添付します
  • 方程式リストが空になるまで繰り返します

うまくいくことを願っています!

JavaScript で作成した数学シミュレータ:

"N"
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

素晴らしいニュース:

  • 期待される計算値が表示されます

悪いニュース:

  • 入力例の 1 つの方程式について、まだ正しい答えが得られません

回答例は間違っているはずがありません...そうですよね??

私が生成し続けている答えは、予想される答えより約 7,000 足りません。

そのため、私のアルゴリズムがこの方程式を正しいものとして識別していないと思われます:

let eqs = input.split('\n').map(line => {
  return [...line.matchAll(/\d+/g)].map(el => +el[0])
})
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

入力例の説明では、これが勝利の方程式です。

function eqChecker(operands, amount, test) {
  if (amount > test) {
    return false
  } else if (amount == test && operands.length == 0) {
    return true
  } else if (operands.length) {
    let copy = operands.slice()
    let first = copy.shift()
    return eqChecker(copy, amount + first, test) || eqChecker(copy, amount * first, test)
  }
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

私のアルゴリズムはその方程式を評価し、次の結果を生成します:

let part1 = eqs.reduce((count, eq) => {
  if (eqChecker(eq.slice(2), eq[1], eq[0])) {
    count += eq[0]
  }
  return count
}, 0)
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

それは、私のアルゴリズムが次のように実行されるためです:

292: 11 6 16 20
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

これが他の数字になる可能性がわかりません。

それで...Google で調べてみました。

そして、いつものように、説明内のわかりやすいサイトに隠れていた自分の答えを見つけました。

すべての演算子は依然として左から右に評価されます。

各再帰関数呼び出しで値を事前に連結していました。

代わりに、私のアルゴリズムは次のようにする必要があります:

11 
11+6 
11+6+16 
11+6+16+20 
11+6+16*20 
11+6+1620 
11+6*16 
11+6*16+20 
11+6*16*20 
11+6*1620 
11+616 
11*6 
11*6+16 
11*6+16+20 
11*6+16*20 
11*6+1620 
11*6*16 
11*616 
116 
116+16 
116+16+20 
116+16*20 
116+1620 
116*16 
11616 
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

何が起こるかを理解したので、その処理動作に合わせてアルゴリズムを調整できますか?

左から右へ…今度は本当に

ありがたいことに、アルゴリズムの調整は比較的簡単でした。

|| を考慮して replaceAll() 句を追加しました。

3 つの項目ごとに処理する新しい while ループは次のようになります。

""
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

そして、return ステートメントの || を調整しました。 2 つの数値を即座に連結する代わりに、これらの文字を含める句。

テストと再テスト

入力例でアルゴリズムを実行しました。

それは ついに正しい答えを生成しました!!

本当に安心しました!!

実行が完了して、パズルの入力に対して正しい答えが生成されるかどうか疑問です。

実行を押しています...

...

...

答えが出ました!

それは大きいので、おそらく良い兆候です。

それは正しい答えですか?

...

いいえ。高すぎます。

残念です。

エッジケースを見逃しているのでしょうか?

私が勝利の方程式を得る条件は、単純に、処理された数学がテスト量と等しいということです。

しかし、変形方程式の 1 つで数値のサブセットが正しい答えを生成できる場合はどうなるでしょうか?

このシナリオを捕らえて除外するために、if 条件を更新してもう 1 つの句を含めました。

"" + "+N"
"" + "*N"
"" + "N"
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この方法では、すべての数値が処理され、結果の量がテスト数値と等しい場合にのみ、方程式がカウントされます。

大きな質問:

  • これによって得られる答えは変わりますか?

もう一度実行を押します...

...

うーん、確かにまだ同じ答えのようですね。

ああ、ちょっと待って、最後の近くに 2 つの数字が違います!

私の新しい答えは、以前よりちょうど 80 少ないものです。

期待値が 80 になる方程式はありますか?

はい!

"N"
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

すべての数字を使わずに 80 を作る方法はありますか?

はい!

"N" + "+N"
"N" + "*N"
"N" + "N"
ログイン後にコピー
ログイン後にコピー

これは除外する必要がある唯一のエッジケースでしたか?

新しい回答を送信中...

正解です!!!

うおおお!!!

やったよ!!!

あれ。だった。疲れる。そして爽快です。そして本当に走ります。そして挑戦的です。

私がこれらのパズルをするのが好きな理由はすべてです。

次へ!

以上が橋の修理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

JavaScriptエンジン:実装の比較 JavaScriptエンジン:実装の比較 Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

Python vs. JavaScript:学習曲線と使いやすさ Python vs. JavaScript:学習曲線と使いやすさ Apr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

C/CからJavaScriptへ:すべてがどのように機能するか C/CからJavaScriptへ:すべてがどのように機能するか Apr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptとWeb:コア機能とユースケース JavaScriptとWeb:コア機能とユースケース Apr 18, 2025 am 12:19 AM

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScript in Action:実際の例とプロジェクト JavaScript in Action:実際の例とプロジェクト Apr 19, 2025 am 12:13 AM

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

JavaScriptエンジンの理解:実装の詳細 JavaScriptエンジンの理解:実装の詳細 Apr 17, 2025 am 12:05 AM

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Python vs. JavaScript:コミュニティ、ライブラリ、リソース Python vs. JavaScript:コミュニティ、ライブラリ、リソース Apr 15, 2025 am 12:16 AM

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

Python vs. JavaScript:開発環境とツール Python vs. JavaScript:開発環境とツール Apr 26, 2025 am 12:09 AM

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

See all articles