Mathematica、Wolfram言語

灘中入試をMathematicaで解く方法 -Part 1-

この記事ではMathematicaの以下の関数を学ぶことができます。

大問1Solve関数
大問2Solve関数Lcm関数
大問3Solve関数
大問4Solve関数 Divisors関数 Mod関数 Length関数
大問5Solve関数
大問6Solve関数 JoinTableUnionの使い方

前回の記事の続きでMathematicaを使った練習問題として灘中の入試(関西で難易度の高い問題)を解いてみようと思います。

MathematicaはソフトがなくてもWebで使用することができます。

Webでの使用方法は以下の記事がおすすめです。

Mathematicaの初心者の方は 大問1→大問3→大問5→大問6→大問4→大問2の順に解くのがおすすめです。

問題の出典

https://nokai.jp/img/kinki/exam-answers/2019/exam_nada_2019_day1.pdf から引用

Mathematicaのコードの使用上の注意点

Mathematicaでは変数をたくさん使用しますが、変数を使用した場合は必ずClearを使用してください。次の問題を解くときに前の変数のデータが残ってしまい、それを使用すると実行結果が変わってしまいます。

aという変数をClearする場合

Clear[a]

大問1 難易度★☆☆☆☆

平成31年度灘中学校入試問題1日目大問1

前回習った内容で解けます。

方程式を解く場合はSolve関数を使用します。

※Mathematicaで右辺と左辺が同じということを表す場合「==」という記号を使用します。後述しますが、右辺を左辺に、左辺を右辺に代入する場合「=」の記号を使用します。

ソースコードのヒントはこちら

Solve関数の使い方は Solve[求めたい方程式,求めたい方程式の記号]

ソースコードの解答例はこちら

Solve[(17 - 77 x)*2019/5 == 31 + 3/5 - 7/13, x]

よって大問1の解答は$\frac{20}{91}$となります。

大問2 難易度★★★☆☆

ヒントはこちら

コードにしやすいように問題の条件を書くとすると

これらの条件をSolve関数の中に入れます。

※mathematicaでは平仮名やカタカナ、漢字を定数にすることは可能ですが、ここではアルファベットを定数にすることをお勧めします。定数は必ず小文字にしてください。大文字で使用する関数と間違えます。

解答のソースコードの例はこちら

※このコードは一例です。他にも方法はあります。

アをa イをb ウをc エをd オをeとします。

Solve[a/bc/d == 1/e && a != b != c != d != e && 2 <= a <= 9 && 2 <= b <= 9 && 2 <= c <= 9 && 2 <= d <= 9 && 2 <= e <= 9 && LCM[a, b] == ab && LCM[c, d] == c*d, {a, b, c, d, e}, Integers]

よって、この問題の答えは6となります。

ソースコードの解説はこちら

先ほどのコードのヒントをコードにします。

1.ア〜オは2~9

 1.ア〜オをアルファベットに直します。アをa 、イをb 、ウをc 、エをd 、オをeとする。

2.a~eは2~9というのは数学的に書くと、それぞれ2≤a≤9,2≤b≤9,2≤c≤9,2≤d≤9,2≤e≤9となります。

2.ア〜オは同じ数ではない

この場合はa≠b≠c≠d≠eこのようになります。

3.ア〜オは整数

この場合はSolve関数の最後にIntegersをつけます。

4.アとイ、ウとエはそれぞれ互いに素でなければならない

この部分はやり方は何通りもあると思いますが、「解答コード」の場合、aとb,cとdの最小公倍数がそれぞれ2数を掛け合わせた数が同じになるという条件にしています。

今までの条件を「&&」ですべて繋げると完成です。

大問3 難易度★★☆☆☆

ソースコードのヒントはこちら

文章をそのままコードにしましょう。

ソースコードの解答例はこちら

すごくむちゃくちゃな気がしますが、一応このコードでもできます。おすすめのコードがある場合はコメントをお願いします。

※このコードは一例です。他にも方法はあります。

Solve[100a + 10b + 1c + 100d + 10e + 1f == 1000 + 10g + 1h &&c + f < 10 && b + e < 10 && a + d >= 10 && 2 <= a <= 9 && 2 <= b <= 9 && 2 <= c <= 9 && 2 <= d <= 9 && 2 <= e <= 9 && 2 <= f <= 9 && 2 <= g <= 9 && 2 <= h <= 9 && a > d, {a, b, c, d, e,
f, g, h}, Integers]

出力された数字を見ると(1) 17 (2) 16 個と分かります。

ソースコードの解答例の解説はこちら

問題文をコードにします。

A,B,C,D,E,F,G,Hはどの2つも異なる2から9までの数字です。

2≤a≤9,2≤b≤9…..2≤h≤9

3桁の整数ABCとDEFを足すと4桁の整数10GHになり、

100a + 10b + 1c + 100d + 10e + 1f == 1000 + 10g + 1h

この足し算でくり上がりは百の位から千の位にだけある。

言い換えると、それぞれ百の位の数字を足し合わせると10を超えるということになるので、

c + f < 10 b + e < 10 a + d >= 10

AがDより大きいとすると…..

A>D

これらを合わせるとソースコードの完成です。

大問4 難易度★☆☆☆☆

こちらは使う関数が分かればたいへん容易にコードを作れます。

コードのヒント

ここで使う関数は

  • 約数を表示(出力)するDivisors関数 
  • 商の余りを表示するMod関数

例: Divisors[a] aの約数を出力する。

例: Mod[{m,n},a] m,nをaで割った時の余りを表示

コードの解答例

②はコードの数値を変えるだけで実行可能なので省略します。

答えは①288 になります。

コードの解答例の解説

aは377の6乗ですので、まずはそれを定義します。

a=377^6

aの約数を表示させる方法はDivisors[a]となります。

aの約数を14で割った時の余りを出力する方法はMod[Divisors[a],14]となります。出力時の1の数を手で数えるのもありですが、コードで一応やります。

ここで、一度その答えを定義します。(この場合はans

ans内に含まれている1を抜き出し、その数を数えるという方法でコードを書きます。

Select[ans,#==1 &, 200]

コードを直訳すると、ansに含まれる1をansの最初から200番目まで調べて抜き出す。ということになります。ここでの200番目と言う数は適当で構いません

次に抜き出された1の数を数えるので、Length関数をつけるとコードの完成です。

大問5 難易度★☆☆☆☆

この問題には条件が3つあります。xとyとzを使うと式が作りやすくなるでしょう。

コードのヒント

仕入れ値をz

1個400円で売ったものの数をx

1個200円で売ったものの数をy個    

ここでの条件は

  • 1個400円でx個売れた時の売り上げと1個200円でy個売れた時の売り上げの合計が26000円
  • 26000円から仕入れ総額を引いた数が11600円
  • 1個400円で売れた品物の数は全体(x+y)の6割より大きく7割より少ない

これらのことをコードにすると完成します。

コードの解答例はこちら

Solve[400x + 200y == 26000 && 26000 - z(x + y) == 11600 && 0.6(x + y) < x < 0.7*(x + y), {x, y, z}, Integers]

このコードよりこの問題の解答は①180円②50個となります。

コードの解答例の解説はこちら
  • 1個400円でx個売れた時の売り上げと1個200円でy個売れた時の売り上げの合計が26000円
  • 26000円から仕入れ総額を引いた数が11600円
  • 1個400円で売れた品物の数は全体(x+y)の6割より大きく7割より少ない

これのそれぞれをコードにします。

  • 1個400円でx個売れた時の売り上げと1個200円でy個売れた時の売り上げの合計が26000円

400x + 200y == 26000

  • 26000円から仕入れ総額を引いた数が11600円

26000 - z(x + y) == 11600

  • 1個400円で売れた品物の数は全体(x+y)の6割より大きく7割より少ない

0.6(x + y) < x < 0.7*(x + y)

以上のコードを&&でつなげるとコードが完成します。

大問6 難易度★☆☆☆☆

この問題ではTableを使うと良いでしょう。

コードのヒント

Tableの使い方は

(例:10の倍数を11個並べる場合)

Table[s*10,{s,11}]

コードを直訳するとsに1~11の数を順番にs×10に代入していくという感じです。

Tableを2つ結合して、重複を消す場合はUnionJoinを使います。

Union[Join[Table[........],Table[........]]]

JoinTableを一つにまとめます。

Unionは一つにまとめられたものの順番を小さい数から順に並び替え、重複を消します。

コードの解答例はこちら

data = Union[Join[Table[s89, {s, 50}], Table[t113, {t, 50}]]]

data[[50]]

コードの解答例はこちら

Union,Join,Tableの使い方はヒントにあります。

Tableの前から50番目の数を出力する場合は[[50]]とします。

コメント

タイトルとURLをコピーしました