与えられた方程式が真である基底を決定する


22

3つの整数が与えられた場合、最初の2つの整数が3番目の整数に乗算するための可能な最小の基底を決定します。生命、宇宙、そしてすべての究極の質問に対する答えを考えるなら、6 * 9 == 42はベース13に当てはまります。

入力には、数字が0〜9、a〜z、およびA〜Zを使用する任意の数字を含めることができます。ここで、a基数10では10、基数10ではZ61です。

入力は任意の方法で入力する必要があり(ハードコーディングを除く)、個々の関数またはプログラム全体を記述できます。

考慮しなければならない最大ベースはベース62、最小ベースはベース2です。

最初の2つの値は3番目の値よりも小さいと仮定できます。また、最小基数は入力の最上位桁/文字よりも1つ大きいと結論付けることができます(たとえば、入力がの3 1a 55場合、最小基数はa最上位桁であるためBase 11になります)。

そのようなベースがない場合、選択したジャンク値を返します。

これはコードゴルフなので、最短のコードが勝ちます。

テストケース

6 9 42     -->   13
a a 64     -->   16
aA bB 36jk -->   41
2 3 20     -->   <junk value>
10 10 100  -->   2

おそらくSTDINの方が良いと思いますし、どちらでもいいでしょう。
エルデハイザー14年

@MartinBüttnerでは、どちらの形式でも入力を許可する必要がありますか?
エルデハイザー14年

1
最後の例(現在は削除されています-10 * 10 = 100)のように複数のベースが有効な場合に行うべきことを明確にするために、ベース10および実際に他の任意のベースでも有効です言及...
クリス・

1
@Kay位置システムをベースb1のような一般的な方法a_0 b^0 + a_1 b^1 + a_2 b^2 + ...a_0最下位桁は)で定義すると、ベース1は間違いなく理にかなっています。最大の現在の数字が0の場合はさらに、OPの結論はまた、検索でベース1が含まれるであろう
マーティン・エンダー

2
基数1について、単項は数体系です。en.m.wikipedia.org/wiki/Unary_numeral_system
erdekhayser

回答:


3

CJam、52 51 48バイト

63,{_ea{i32b~\([G-35-9]=-_Xe>:X;}f%fbW%~*=\X>*}#

ここでテストしてください。オンラインテスターは、ARGVを介した入力をサポートしていません。最も近い代替方法は、入力6 9 42をSTDIN に入れて使用することです。

lS/:E;
63,{_E{i32b~\([G-35-9]=-_Xe>:X;}f%fbW%~*=\X>*}#

-162までの有効なベースが見つからない場合に出力されます。

数字解析コードについてPeterに感謝します!

カウントに14バイトを追加した多くの問題を修正しました。以下の説明は元の提出物に関するものであり、明日いつか更新します。

63,{_ea{i32b~\([G-35-9]=-_Xe>:X;}f%fbW%~*=\X>*}#
63,                                              "Push the array [0 1 .. 62].";
   {                                          }# "Find the first index for which the block returns
                                                  a truthy value.";
    _                                            "Duplicate the current base.";
     ea                                          "Read ARGV into an array of strings.";
       {                        }f%              "Apply this block to each character.";
        i32b                                     "Convert to code point, and then to base-32. The
                                                  most significant digit now identifies the 'type'
                                                  of digit.";
            ~\(                                  "Unwrap the array. Swap the digits. Decrement.";
               [G-35-9]                          "Push array [16 -35 -9] of digit offsets.";
                       =-                        "Select the relevant offset and subtract it from 
                                                  the least significant digit.";
                         _                       "Duplicate the current digit D.";
                          Xe>:X;                 "X := max(X,D). X is predefined as 1.";
                                   fb            "Convert all numbers to the current base.";
                                     W%          "Reverse the list of numbers.";
                                       ~         "Unwrap the array.";
                                        *=       "Multiply factors. Check equality with product.";
                                          \      "Swap result with current base.";
                                           X>    "Ensure base is greater than X.";
                                             *   "Multiply boolean results.";

インデックスは、プログラムの最後に自動的に印刷されます。


GSでは、数字をとして解析できます32base~\[-16.35 9]=+。CJamの基本変換が短いことは知っています。
ピーターテイラー

7

APL(Dyalog Unicode)、30 バイトSBCS

⊢{3e=×/2e←⍵⊥⍺:⍵⋄⍺∇⍵+1}1+⌈/∘,

オンラインでお試しください!

Adámに助けてくれてありがとう。

説明:

⊢{3e=×/2e←⍵⊥⍺:⍵⋄⍺∇⍵+1}1+⌈/∘,  
                               left argument ⍺: the vector (do nothing)
                        1+⌈/∘,  right argument ⍵: our starting base.
                             ,              start by flattening the matrix of arguments                               ⌈/                reduce by max (find the highest number)
                                           compose both of these together
                        1+                  increment by one
 {         ⍵⊥⍺         }        convert inputs to the current base
 {       e            }        store the converted values in 3
 {      2             }        take the first 2 values
 {    ×/               }        multiply them together (reduce-multiply)
 {  e=                 }        compare with e (the converted inputs)
 {3                   }        only keep the result of the comparison with the 3rd element (expected result)
 {             :⍵      }        if truthy, return the current base.
 {                    }        otherwise...
 {                ⍺∇⍵+1}        ...recurse with the base incremented

ヘルパー関数を使用してIn、入力をより口当たりの良い形式で受け取ります。それ以外の場合、入力は3列の行列を受け取ります。

'3 9 42' たとえば、次のようになります(トップダウン、次に左から右に読みます):

0 0 4
3 9 2

そして'aA bB 36jk'(ここでも同じaです。10は、b11 Aは36です、など)

 0  0  3
 0  0  6
10 11 19
36 37 20

2

Python 2-197 213

なんて怪物...(CJamと比較して)

from string import*
I=raw_input()
x,y,z=I.split()
B=lambda s,b:sum(b**i*(digits+lowercase+uppercase).find(s[-i-1])for i in range(len(s)))
print([b for b in range(B(max(I),10)+1,62)if B(x,b)*B(y,b)==B(z,b)]+[0])[0]

残念ながら、intのベース変換は36までのベースのみを処理できます。そのため、自分で実装する必要がありました。(この素晴らしいソリューションをご覧ください。)


これは、最大桁以下のベースを返さないことを確認しますか?
マーティンエンダー14年

@MartinBüttner:よく分かりません。少なくとも明示的には。これが問題になるテストケースはありますか?(実際には、テストケースの生成はOPが処理する必要があります...)
ファルコ14年

エラーの場合、基数3を持つ2 * 3 = 20を試してください。3は、3進数システムの数字ではありません。
kay 14年


1

JavaScriptの(E6)129 139

2から62までのすべてのベースを再帰的に試行し、値に問題がない場合は-1を返します。
JavaScriptのparseInt関数は最大36個のベースで動作するため、より大きなベースには少し助けが必要です。
パラメーターx、y、zは数字ではなく文字列であることに注意してください。
見た目よりも難しいです。最初のバージョンの基本的なバグを指摘してくれたMartinに感謝します。

F=(x,y,z,b=2,N=n=>[for(d of(t=0,n))t=(v=parseInt(d,36)+(d>'@'&d<'a')*26)<b?t*b+v:NaN]&&t)=>b<63?N(x)*N(y)!=N(z)?F(x,y,z,b+1):b:-1

少ないゴルフ

F=(x,y,z,b=2,
   D=d=>parseInt(d,36)+(d>'@'&d<'a')*26, // parse a single digit
   N=n=>[for(d of(t=0,n))t=(v=D(d))<b?t*b+v:NaN]&&t // parse a string
)=>b<63?N(x)*N(y)!=N(z)?F(x,y,z,b+1):b:-1

FireFox / FireBugコンソールでテストします。
テストでは、異なる基数(62ではなく36まで)で1000個の数値を試します。見つかったベースは正しいが、テストケースを生成したベースよりも少ない可能性があることに注意してください。

for(i=0;i<1000;i++)
{
   x=Math.random()*100|0,y=Math.random()*100|0,z=x*y,b=Math.random()*35+2|0
   bx=x.toString(b),by=y.toString(b),bz=z.toString(b),
   nb=F(bx,by,bz)
   nx=parseInt(bx,nb),ny=parseInt(by,nb),nz=parseInt(bz,nb)
   // if (nx*ny != nz) // uncomment to se output for errors only
     console.log(x,y,z,'base '+b,bx,by,bz, 'found base '+nb,nx,ny,nz,nx*ny)
}

@MartinBüttnerパラメーターは文字列です(可能な値はaA bB 36jkなどです)。答えを明確にしました。
edc65 14年

ああ、それは理にかなっています。
マーティンエンダー14年

1

、28バイト

I⌊Φ…⊕⍘⌈⁺⁺θηζ⁶²¦⁶³⁼×⍘θι⍘ηι⍘ζι

オンラインでお試しください!リンクは、コードの詳細バージョンです。None有効なベースが見つからない場合に出力します。説明:

         θ                      First input
        ⁺                       Concatenated with
          η                     Second input
       ⁺                        Concatenated with
           ζ                    Third input
      ⌈                         Maximum character (by ordinal)
     ⍘                          Converted from base
            ⁶²                  Literal 62
    ⊕                           Incremented
   …                            Range up to
               ⁶³               Literal 63
  Φ                             Filtered by
                    θ           First input
                   ⍘            Converted from base
                     ι          Current value
                  ×             Multiplied by
                       η        Second input
                      ⍘         Converted from base
                        ι       Current value
                 ⁼              Equals
                          ζ     Third input
                         ⍘      Converted from base
                           ι    Current value
 ⌊                              Minimum
I                               Cast to string
                                Implicitly print

投稿した実際のコードを使用するTIOプログラムを持つことは可能ですか?
mbomb007

@ mbomb007 オンラインで試すことができます!しかし、ASTジェネレーターAny何らかの理由で考えているようです...
ニール

0

アーラン(escript)-200

main(X)->m(2,X).
m(63,_)->0;m(C,X)->try[F,G,I]=[c(0,C,Y)||Y<-X],I=F*G,io:fwrite("~p",[C])catch _:_->m(C+1,X)end.
c(A,B,[H|T])->D=H-if$A>H->$0;$a>H->29;0<1->87end,if D<B->c(A*B+D,B,T)end;c(A,_,_)->A.

存在する必要がある2つの主要な改行を追加します。

読みやすい:

#!/usr/bin/env escript

main(Args) -> test(2, Args).

test(63, _) -> 0;
test(Base, Args) ->
    try
        [Factor1, Factor2, Product] = [convert(0, Base, Arg) || Arg <- Args],
        Product = Factor1 * Factor2,
        io:fwrite("~p", [Base])
    catch _:_ ->
        test(Base + 1, Args)
    end.

convert(Accumulator, Base, [Head|Tail]) ->
    Digit = Head - if Head < $A -> $0;
                      Head < $a -> $A - 10 - 26;
                      true      -> $a - 10
                   end,
    if Digit < Base ->
        convert(Accumulator * Base + Digit, Base, Tail)
    end;
convert(Accumulator, _, _) -> Accumulator.

呼び出し:

$ escript x.erl 6 9 42
13
$ escript -i x.erl a a 64
16
$ escript -i x.erl aA bB 36jk
41
$ escript -i x.erl 2 3 20
(no output)
$ escript -i x.erl 10 10 100
2

これは、最大桁以下のベースを返さないことを確認しますか?
マーティンエンダー14年

はい、if Digit < Base -> … end部品がそれを処理します。場合はifブロックが真の枝を持っていない場合、例外はに挟まるれ、スローされますtry … catch _:_ -> … end
kay 14年

0

Haskell 216文字(177?)

これを可能な限りゴルフしようとしました。インポートがカウントされる場合、これは私の最短コード(216)

import Data.Char
import Data.List
m=maximum
j[]=0;j(x:_)=x
f=reverse.map(\x->ord x-48)
g[]_=0;g(m:n)x=m+x*g n x
main=do
l<-getLine
let k@[x,y,z]=words l
print$j[n|n<-[2..62],g(f x)n*g(f y)n==g(f z)n,n>(m.map(m.f)$k)]

ただし、インポートがカウントされなかった場合、これは私の最高のバージョンです(177):

import Data.Char
import Data.List
import Control.Applicative
m=maximum
j[]=0;j(x:_)=x
f=reverse.map(\x->ord x-48)
g[]_=0;g(m:n)x=m+x*g n x
main=words<$>getLine>>= \k@[x,y,z]->print$j[n|n<-[2..62],g(f x)n*g(f y)n==g(f z)n,n>(m.map(m.f)$k)]

これは、係数がxより大きくないという条件で、各数値を多項式P(x)として扱います。次に、可能な各ベースで多項式を評価し、等式P(x)* Q(x)= R(x)を満たすベースに到達すると停止します。「ベースは最大桁よりも大きい」というルールは、パターンマッチの最後のガード(つまり)で実施されn>(m.map(m.f)$k)ます。異なるゴルフチャレンジと異なるチャレンジメーカーは、スコアリングに対する輸入に関して異なるポリシーを持っていることを知っているので、2番目のゴルフコースを塩味のあるものにしましょう。


実際のソリューションは、それぞれ216および177バイト/文字です。しかし、OPで明示的に指定されていない限りインポートカウントされるため、2番目の解決策は無効です。
nyuszika7h 14年

0

プロローグ-195バイト

基本的に私のErlangの答えと同じアイデア:

:-use_module(library(main)).
main(A):-between(2,62,B),maplist(x(B),A,[F,G,P]),0is F*G-P,write(B).
c(I,B,Q,O):-Q=[H|T]->(H<65->D=48;H<97->D=29;D=87),H-D<B,c(I*B+H-D,B,T,O);O=I.
c(B)-->name,c(0,B).

読みやすい:

:- use_module(library(main)).

main(Args) :-
    between(2, 62, Base),
    maplist(convert(Base), Args, [Factor1, Factor2, Product]),
    0 is Factor1 * Factor2 - Product,
    write(Base).

convert(Accumulator, Base, List, Output) :-
    List = [Head|Tail] ->
        (   Head < 65 -> Offset = 48;
            Head < 97 -> Offset = 29;
                         Offset = 87),
        Head - Offset < Base,
        convert(Accumulator * Base + Head - Offset, Base, Tail, Output);
    Output = Accumulator.

convert(Base, Input, Output) :-
    name(Input, List),
    convert(0, Base, List, Output).

呼び出し:

$ swipl -qg main x.pl 6 9 42
13
$ swipl -qg main x.pl aA bB 36jk
41
$ swipl -qg main x.pl 2 3 20
ERROR: Unknown message: goal_failed(main([2,3,20]))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.