Verilen Denklemin Doğru Olduğu Tabanı Belirleme


22

3 tamsayı verildiğinde, ilk iki tamsayının üçüncü ile çarpması için mümkün olan en düşük temeli belirleyin. Nihai Yaşam Sorusuna Cevap, Evren ve Her Şeye Cevabı düşünüyorsanız, 6 * 9 == 42, Üstat 13'te doğrudur.

Girişler, basamakları 0-10, az ve AZ karakterlerini kullanan, aTaban 10'daki 10'a eşit ve Taban 10'daki Z61 olan herhangi bir sayı içerebilir .

Girişler istediğiniz şekilde (kodlama hariç) girilmelidir ve kişisel bir işlev veya tüm bir program yazabilirsiniz.

Göz önünde bulundurulması gereken en yüksek taban, Taban 62'dir ve minimum taban, Taban 2'dir.

İlk iki değerin üçüncü değerden daha küçük olduğunu varsayabilirsiniz. Ayrıca, minimum tabanın girişlerden en yüksek basamaktan / karakterden daha büyük olduğu sonucuna varabilirsiniz (örneğin, eğer girdilerse 3 1a 55, minimum taban a, en yüksek basamak olduğu için Taban 11 olacaktır ).

Eğer böyle bir temel yoksa, tercih ettiğiniz önemsiz bir değeri döndürün.

Bu kod golf, yani en kısa kod kazanır.

Test Kılıfları

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

Bence STDIN muhtemelen daha iyi olurdu ve her ikisi de iyi olurdu.
erdekhayser

@ MartinBüttner Öyleyse her iki şekilde de girişe izin vermeli miyim?
erdekhayser

1
Bir açıklama noktası olarak, son örneğiniz (şimdi kaldırılmış olan - 10 * 10 = 100 idi) gibi birden fazla üs geçerliyse, üs 10'da geçerli olduğu ve esasen ilgilendiğiniz diğer bütün üslerin de geçerli olduğu durumda yapılması gerekenler söz ...
Chris,

1
@Kay Eğer konumsal sistemi tabandaki bgenel olarak a_0 b^0 + a_1 b^1 + a_2 b^2 + ...( a_0en az önemli basamak olan) taban 1'den daha iyi tanımlarsam kesinlikle mantıklı olur. Ayrıca, OP'nin vardığı sonuç, eğer mevcut en büyük rakam 0 ise, aramada 1 numaralı üssü de içerecektir.
Martin Ender

2
Temel 1 ile ilgili olarak, unary bir sayı sistemidir. en.m.wikipedia.org/wiki/Unary_numeral_system
erdekhayser

Yanıtlar:


3

CJam, 52 51 48 bayt

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

Burada test et. Çevrimiçi test cihazı ARGV üzerinden girişi desteklemiyor. En yakın alternatif, girişi 6 9 42STDIN'e koymak ve kullanmaktır:

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

Bu yazdırır -1 , 62'ye kadar geçerli bir taban bulunamadığında .

Rakam ayrıştırma kodu için Peter için çok teşekkürler!

Sayıya 14 bayt ekleyen bir çok sorunu düzelttim. Aşağıdaki açıklama hala orjinal gönderim için ve yarın biraz zaman güncelleyeceğim.

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

Endeks program sonunda otomatik olarak yazdırılır.


GS’de rakamlar ayrıştırılabilir 32base~\[-16.35 9]=+. CJam'ın daha kısa taban dönüşümüne sahip olduğunu biliyorum.
Peter Taylor

7

APL (Dyalog Unicode) , 30 bayt SBCS

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

Çevrimiçi deneyin!

Yardım için Adám'a teşekkürler.

Açıklama:

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

Bir yardımcı işlev kullanıyoruz InGirişi daha lezzetli bir formata almak için . Aksi halde girdi 3 sütunluk bir matris alır.

'3 9 42' Örneğin, (yukarıdan aşağıya, daha sonra soldan sağa) oku

0 0 4
3 9 2

Ve 'aA bB 36jk'(burada aynı. a10, b11, A36, vb.)

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

2

Python 2 - 197 213

Ne canavar ... (CJam'a kıyasla)

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]

Maalesef, inttemel dönüşüm yalnızca 36'ya kadar olan üsleri kaldırabiliyor. Bu yüzden kendi başıma uygulamam gerekiyordu. ( Bu harika çözüme bakın .)


Bu, bir tabanı en büyük hanelere eşit ya da ondan daha düşük bir değere döndürmemeyi sağlıyor mu?
Martin Ender

@ MartinBüttner: Emin değilim. En azından açıkça değil. Bunun bir sorun olduğu bir test vakanız var mı? (Aslında, test vakalarının oluşturulması OP tarafından halledilmeli ...)
Falko

Bir hata durumunda 3 numaralı tabanı olan 2 * 3 = 20'yi deneyin. Üçlü sayı sistemindeki 3 rakam bir rakam değildir.
kay

2

CJam, 53 bayt

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

STDIN gibi üç girişi alır

6 9 42

Baskılar 0Herhangi bir tabandaki ürün mümkün değilse

Daha fazla golf yapmaya çalışacağım.

Burada dene


1

JavaScript (E6) 129 139

2'den 62'ye kadar olan tüm bazları tekrar tekrar deneyin, hiçbir değer yolunda değilse -1'e dönün.
JavaScript parseInt işlevi 36'ya kadar tabanla çalışır, bu nedenle daha büyük tabanlar için biraz yardım gerekir.
Dikkat edin, x, y, z parametreleri sayı değil, dizgedir.
Göründüğünden daha zor. Martin'e ilk versiyonda temel bir hatayı işaret ettiği için teşekkür ederiz.

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

Daha az golf oynadı

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 konsolunda test edin .
Test farklı bazlarda 1000 sayı deniyor (en fazla 36, ​​62 değil). Bulunan tabanın doğru olabileceğine, ancak test senaryosunu oluşturan tabandan daha az olduğuna dikkat çekmek önemlidir.

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 parametreleri dizgedir (mümkün olan değerler A bB 36jk ... gibi birşeydir). Cevap açıklığa kavuşturuldu.
edc65

Oh doğru, bu mantıklı.
Martin Ender

1

Kömür , 28 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. NoneGeçerli bir taban bulunamadığında çıktılar . Açıklama:

         θ                      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

Gönderdiğiniz asıl kodu kullanan bir TIO programına sahip olmak mümkün mü?
mbomb007

@ mbomb007 Çevrimiçi Deneyin! ancak jeneratör düşünüyor AST olduğunu Any... nedense
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.

Mevcut olması gereken iki yeni satır ekleyin.

Okunabilir:

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

çağırma:

$ 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

Bu, bir tabanı en büyük hanelere eşit ya da ondan daha düşük bir değere döndürmemeyi sağlıyor mu?
Martin Ender

Evet, if Digit < Base -> … endparça ilgilenir. Bir ifbloğun gerçek bir dalı yoksa, yakalanan bir istisna atılır try … catch _:_ -> … end.
kay

0

Haskell 216 karakter (177?)

Bu mümkün olduğunca golf oynamaya çalıştı. İthalat sayılırsa, bu benim en kısa kodum (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)]

Ancak, ithalat sayılmamıştı, o zaman bu benim en iyi sürümüm (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)]

Bu, her sayıya, x'in taban olduğu, (katsayıların x'den büyük olmaması koşuluyla) bir polinom P (x) gibi davranır; Sonra polinomları olası her bir taban üzerinde değerlendirip, P (x) * Q (x) = R (x) eşitliğini sağlayan birine geldiğimde durdum. 'Temel, en büyük basamaktan daha büyüktür' kuralı, örüntü maçındaki son bekçi ile uygulanır n>(m.map(m.f)$k). Farklı golf sahası mücadelelerinin ve farklı meydan okuyucuların puanlamaya karşı ithalat konusunda farklı politikaları olduğunu biliyorum, bu yüzden ikincisini bir tuz tuzu ile alın.


Çözümler aslında sırasıyla 216 ve 177 bayt / karakterdir. İthalat nedeniyle Ama ikinci çözüm, geçersiz olan OP açıkça bildiğim kadarıyla söyleyebilirim burada durum böyle değil, hangi tarafından aksi belirtilmedikçe sayılır.
nyuszika7h

0

Prolog - 195 bayt

Temelde Erlang cevabımla aynı fikir:

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

Okunabilir:

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

çağırma:

$ 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]))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.