Bestimmen Sie die Basis, auf der eine gegebene Gleichung wahr ist

22

Bestimmen Sie bei 3 gegebenen Ganzzahlen die niedrigstmögliche Basis für die ersten beiden Ganzzahlen, um sie mit der dritten zu multiplizieren. Wenn Sie an die Antwort auf die ultimative Frage des Lebens denken, ist das Universum und alles, 6 * 9 == 42, in der Basis 13 wahr.

Die Eingaben können beliebige Zahlen enthalten, deren Ziffern die Zeichen 0-9, az und AZ enthalten a in Basis 10 10 und Zin Basis 10 61 gleich sind.

Die Eingaben sollten nach Belieben eingegeben werden (mit Ausnahme der Hardcodierung), und Sie können entweder eine einzelne Funktion oder ein gesamtes Programm schreiben.

Die maximale Basis, die berücksichtigt werden muss, ist Basis 62 und die minimale Basis ist Basis 2.

Sie können davon ausgehen, dass die ersten beiden Werte kleiner als der dritte sind. Sie können auch den Schluss ziehen, dass die minimale Basis eine Stelle größer ist als die höchste Ziffer / das höchste Zeichen der Eingaben (wenn die Eingaben beispielsweise sind 3 1a 55, wäre die minimale Basis die Basis 11, weila es sich um die höchste Ziffer handelt).

Wenn es keine solche Basis gibt, geben Sie einen Junk-Wert Ihrer Wahl zurück.

Dies ist Codegolf, also gewinnt der kürzeste Code.

Testfälle

6 9 42     -->   13
a a 64     -->   16
aA bB 36jk -->   41
2 3 20     -->   <junk value>
10 10 100  -->   2
erdekhayser
quelle
Ich denke, STDIN wäre wahrscheinlich besser, und beides wäre in Ordnung.
Erdekhayser
@ MartinBüttner Soll ich also nur Eingaben in irgendeiner Form zulassen?
Erdekhayser
1
Zur Verdeutlichung, was zu tun ist, wenn mehrere Basen gültig sind, z. B. Ihr letztes Beispiel (das jetzt entfernt wurde - es war 10 * 10 = 100), wobei es auch in Basis 10 und in jeder anderen von Ihnen gewünschten Basis gültig ist Erwähnen Sie ...
Chris
1
@ Kay Wenn ich das Positionssystem in der Basis bauf eine allgemeine Art und Weise wie a_0 b^0 + a_1 b^1 + a_2 b^2 + ...(wo a_0ist die niedrigstwertige Ziffer) definiere, ist Basis 1 definitiv sinnvoll. Darüber hinaus würde die Schlussfolgerung des OP auch die Basis 1 in die Suche einbeziehen, wenn die größte derzeitige Ziffer 0 ist.
Martin Ender,
2
Über Basis 1 ist Unär ein Zahlensystem. en.m.wikipedia.org/wiki/Unary_numeral_system
erdekhayser

Antworten:

3

CJam, 52 51 48 Bytes

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

Teste es hier. Der Online-Tester unterstützt keine Eingabe über ARGV. Die 6 9 42naheliegendste Alternative besteht darin, die Eingabe wie in STDIN zu setzen und Folgendes zu verwenden:

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

Dies wird gedruckt, -1wenn keine gültige Basis bis zu 62 gefunden werden kann.

Vielen Dank an Peter für den Ziffern-Parsing-Code!

Ich habe viele Probleme behoben, durch die die Anzahl um 14 Bytes erhöht wurde. Die folgende Erklärung gilt immer noch für meine ursprüngliche Einreichung und ich werde sie morgen einige Zeit aktualisieren.

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.";

Der Index wird am Ende des Programms automatisch ausgedruckt.

Martin Ender
quelle
In GS können die Ziffern als geparst werden 32base~\[-16.35 9]=+. Ich weiß, dass CJam eine kürzere Basiskonvertierung hat.
Peter Taylor
7

APL (Dyalog Unicode) , 30 Byte SBCS

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

Probieren Sie es online!

Vielen Dank an Adám für die Hilfe.

Erläuterung:

⊢{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

Wir verwenden eine Hilfsfunktion, Inum die Eingabe in ein schmackhafteres Format zu bringen. Ansonsten erhält die Eingabe eine Matrix aus 3 Spalten.

'3 9 42' würde zum Beispiel geben (von oben nach unten und dann von links nach rechts lesen):

0 0 4
3 9 2

Und für 'aA bB 36jk'(dasselbe hier. aIst 10, bist 11, Aist 36, usw.)

 0  0  3
 0  0  6
10 11 19
36 37 20
Ven
quelle
2

Python 2 - 197 213

Was für ein Monster ... (im Vergleich zu 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]

Leider kann intdie Basiskonvertierung nur Basen bis zu 36 verarbeiten. Daher musste ich sie selbst implementieren. (Siehe diese wunderbare Lösung .)

Falko
quelle
Stellt dies sicher, dass keine Basis zurückgegeben wird, die kleiner oder gleich den größten Ziffern ist?
Martin Ender
@ MartinBüttner: da bin ich mir nicht sicher. Zumindest nicht explizit. Haben Sie einen Testfall, bei dem dies ein Problem darstellt? (Eigentlich sollte sich das OP um das Generieren von Testfällen kümmern ...)
Falko
Versuchen Sie 2 * 3 = 20, was in einem Fehlerfall die Basis 3 hat. 3 ist keine Ziffer in einem ternären Zahlensystem.
kay
2

CJam, 53 Bytes

lA,s'{,97>+'[,65>+f#_$W=1e>)63,>_@Wa/W%f{fb~*=}1#\0+=

Nimmt die drei Eingaben von STDIN gerne entgegen

6 9 42

Druckt 0 wenn das Produkt in einer beliebigen Basis nicht möglich ist

Ich werde versuchen, weiter Golf zu spielen.

Probieren Sie es hier aus

Optimierer
quelle
1

JavaScript (E6) 129 139

Versuchen Sie rekursiv alle Basen von 2 bis 62 und geben Sie -1 zurück, wenn kein Wert in Ordnung ist.
Die JavaScript-Funktion parseInt arbeitet mit einer Basis von bis zu 36, daher ist für größere Basen eine kleine Hilfe erforderlich.
Achtung, die Parameter x, y, z sind Strings, keine Zahlen.
Es ist schwieriger als es scheint. Vielen Dank an Martin für den Hinweis auf einen grundlegenden Fehler in der ersten Version.

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

Weniger golfen

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

Test In FireFox / Firebug - Konsole.
Der Test versucht 1000 Nummern mit verschiedenen Basen (bis zu 36, nicht 62). Es ist erwähnenswert, dass die gefundene Basis korrekt sein könnte, aber weniger als die Basis, die den Testfall generiert hat.

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)
}
edc65
quelle
@ MartinBüttner die parameter sind strings (mögliche werte sind so etwas wie aA bB 36jk ...). In der Antwort geklärt.
Edc65
Oh ja, das macht Sinn.
Martin Ender
1

Kohle , 28 Bytes

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Gibt aus, Noneob keine gültige Basis gefunden werden kann. Erläuterung:

         θ                      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
Neil
quelle
Ist es möglich, ein TIO-Programm zu haben, das den tatsächlich von Ihnen geposteten Code verwendet?
mbomb007
@ mbomb007 Du kannst es online ausprobieren ! aber die AST - Generator scheint zu denken , ist Anyaus irgendeinem Grunde ...
Neil
0

Erlang (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.

Fügen Sie zwei führende Zeilen hinzu, die vorhanden sein müssen.

In lesbarem:

#!/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.

Aufruf:

$ 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
Kay
quelle
Stellt dies sicher, dass keine Basis zurückgegeben wird, die kleiner oder gleich den größten Ziffern ist?
Martin Ender
Ja, das if Digit < Base -> … endTeil kümmert sich darum. Wenn ein ifBlock keine echte Verzweigung hat, wird eine Ausnahme ausgelöst, die abgefangen wird try … catch _:_ -> … end.
kay
0

Haskell 216 char (177?)

Ich habe versucht, so viel wie möglich Golf zu spielen. Wenn Importe gezählt werden, ist dies mein kürzester Code (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)]

Wurden die Importe jedoch nicht gezählt, so ist dies meine beste Version (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)]

Dies behandelt jede Zahl als ein Polynom P (x), wobei x die Basis ist, unter der Bedingung, dass kein Koeffizient größer als x ist; Ich bewerte dann die Polynome über jede mögliche Basis und höre auf, wenn ich eines erreiche, das die Gleichheit P (x) * Q (x) = R (x) erfüllt. Die Regel "Basis ist größer als die größte Ziffer" wird mit dem letzten Wächter in der Musterübereinstimmung durchgesetzt, nämlich n>(m.map(m.f)$k). Ich weiß, dass unterschiedliche Golfherausforderungen und unterschiedliche Herausforderer unterschiedliche Richtlinien in Bezug auf den Import in Bezug auf die Wertung haben. Nehmen Sie also die zweite mit einem Körnchen Salz.

Archaephyrryx
quelle
Die Lösungen sind 216 bzw. 177 Bytes / Zeichen. Aber die zweite Lösung ist ungültig, da die Importe sind gezählt , wenn der OP ausdrücklich anders festgelegt, was nicht der Fall ist hier, soweit ich das beurteilen kann.
nyuszika7h
0

Prolog - 195 Bytes

Grundsätzlich die gleiche Idee wie meine Erlang-Antwort:

:-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).

In lesbarem:

:- 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).

Aufruf:

$ 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]))
Kay
quelle