Yalnızca 0-9 ve dört işlemle bir sayıyı ifade etme


14

açıklama

Befunge , yığınları kullanan iki boyutlu bir programdır .

Yani, 5 + 6 yapmak için şunu yazıyorsunuz 56+, yani:

56+
5    push 5 into stack
 6   push 6 into stack
  +  pop the first two items in the stack and add them up, and push the result into stack

(to those of you who do not know stacks, "push" just means add and "pop" just means take off)

Bununla birlikte, zekanızın gözlemlediği gibi, sayıyı 56doğrudan yığının içine itemeyiz.

Bunu yapmak için, biz yazmalısınız 78*hangi çarpar, yerine 7ve 8ve yığın haline ürünü iter.

ayrıntılar

Giriş, programcının takdirine bağlı olarak herhangi bir biçimde alınabilir, yani STDIN olabilir veya olmayabilir.

Giriş pozitif bir tamsayı olacaktır (dahil etme 0veya negatif tamsayılar için bonus olmaz ).

Çıktı bir dize yalnızca bu karakterden oluşan olacaktır: 0123456789+-*/(ı ediyorum değil kullanmak %. Modulo)

Amaç, yukarıda açıklanan formatı kullanarak girişi temsil edebilecek en kısa dizeyi bulmaktır .

Örneğin, giriş ise 123, çıkış olur 67*99*+. Çıktı soldan sağa doğru değerlendirilmelidir.

Birden fazla kabul edilebilir çıktı varsa (örn. Kabul 99*67*+edilebilir), herhangi biri yazdırılabilir (hepsini yazdırmak için bonus olmaz).

Daha fazla açıklama

Hala nasıl 67*99*+değerlendirildiğini anlamıyorsanız 123, işte ayrıntılı bir açıklama.

stack    |operation|explanation
          67*99*+
[6]       6         push 6 to stack
[6,7]      7        push 7 to stack
[42]        *       pop two from stack and multiply, then put result to stack
[42,9]       9      push 9 to stack
[42,9,9]      9     push 9 to stack
[42,81]        *    pop two from stack and multiply, then put result to stack
[123]           +   pop two from stack and add, then put result to stack

TL; DR

Program , yukarıda belirtilen formatı kullanarak girişi (sayı) temsil edebilecek en kısa dizeyi bulmalıdır .

notlar

Bu bir mücadelesi, bu yüzden bayttaki en kısa kod kazanır.

Netleştirme

-Ya olabilir x-yveya y-xprogramcı takdirine bağlı olarak,. Bununla birlikte, seçim çözüm içinde tutarlı olmalıdır. Aynı şekilde /.

Örnek program

Lua, 1862 bayt ( çevrimiçi deneyin )

Ben yazar olduğum için, ben hiç golf olmaz.

Açıklama:

This uses the depth-first search method.

Önce derinlemesine arama hakkında daha fazla bilgi: burada .

Program:

local input = (...) or 81

local function div(a,b)
    if b == 0 then
        return "error"
    end
    local result = a/b
    if result > 0 then
        return math.floor(result)
    else
        return math.ceil(result)
    end
end

local function eval(expr)
    local stack = {}
    for i=1,#expr do
        local c = expr:sub(i,i)
        if c:match('[0-9]') then
            table.insert(stack, tonumber(c))
        else
            local a = table.remove(stack)
            local b = table.remove(stack)
            if a and b then
                if c == '+' then
                    table.insert(stack, a+b)
                elseif c == '-' then
                    table.insert(stack, b-a)
                elseif c == '*' then
                    table.insert(stack, a*b)
                elseif c == '/' then
                    local test = div(b,a)
                    if test == "error" then
                        return -1
                    else
                        table.insert(stack, a+b)
                    end
                end
            else
                return -1
            end
        end
    end
    return table.remove(stack) or -1
end

local samples, temp = {""}, {}

while true do
    temp = {}
    for i=1,#samples do
        local s = samples[i]
        table.insert(temp, s..'0')
        table.insert(temp, s..'1')
        table.insert(temp, s..'2')
        table.insert(temp, s..'3')
        table.insert(temp, s..'4')
        table.insert(temp, s..'5')
        table.insert(temp, s..'6')
        table.insert(temp, s..'7')
        table.insert(temp, s..'8')
        table.insert(temp, s..'9')
        table.insert(temp, s..'+')
        table.insert(temp, s..'-')
        table.insert(temp, s..'*')
        table.insert(temp, s..'/')
    end
    for i=1,#temp do
        if input == eval(temp[i]) then
            print(temp[i])
            return
        end
    end
    samples = temp
end

Bonus

Kodu yazmak için Befunge (veya herhangi bir varyantını) kullanırsanız sizin için bir pasta .


3
Her zaman en sıradan dizeyi üretiyorsa, bir cevap verildiğinde karar vermek zor olabilir. Bir fikir, büyük bir dizi 30–50 sayı üretmek ve tüm çıktı dizesi uzunluğunun toplamına göre puan almak olacaktır. Ancak, bu skor kod uzunluğu ile birleştirmek nasıl emin değilim
Luis Mendo

4
Alt kümesidir bu .
Addison Crump

2
Dan düşüncelerimi üzerinde kopyalama sohbet : "Bunu düşündüm ama alt kümesi çok daha basit şeyler yapar iddia ediyorum çünkü 1) hiçbir altıgen, 2) hiçbir yüzen, 3) hiçbir çoğaltılması ve 4) pozitif yalnızca"
SP3000

1
@CoolestVeto bu eski cevapları geçersiz kılacak kadar farklı.
Rɪᴋᴇʀ

1
@CoolestVeto Bence diğer zorluk bunun bir kopyası olarak kapatılmalıdır.
mbomb007

Yanıtlar:


4

Python 2, 278 bayt

Her zaman en kısa cevabı veren en iyi çözümüm. (ama çok yavaş)

def e(c):
 s=[];x,y=s.append,s.pop
 while c:
  d,c=c[0],c[1:]
  if"/"<d<":":x(d)
  else:a,b=y(),y();x(str(eval(b+d+a)))
 return int(y())
def g(v):
 s="0123456789+-*";t=list(s)
 while 1:
  for x in t:
   try:
    if e(x)==v:return x
   except:0
  t=[x+y for x in t for y in s]

Python 2, 437 bayt

Bu çözüm daha uzun, ancak çok hızlıdır (kaba kuvvet değil). Ve eminim ki, her zaman mümkün olan en kısa sonucu döndürür.

r=range;l=len;a=input()
def f(n):
 if n<=9:return str(n)
 for d in r(9,1,-1):
  if n%d==0:return f(n/d)+"%d*"%d
 h=sum(map(int,list(str(n))))%9
 return f(n-h)+"%d+"%h
m={x:f(x) for x in r(a*9)}
for b in m:
 if a-b in m and l(m[b])+l(m[a-b])+1<l(m[a]):m[a]=m[a-b]+m[b]+"+"
 if a+b in m and l(m[b])+l(m[a+b])+1<l(m[a]):m[a]=m[a+b]+m[b]+"-"
 if b!=0 and a%b==0 and a/b in m and l(m[b])+l(m[a/b])+1<l(m[a]):m[a]=m[a/b]+m[b]+"*"
print m[a]

2
PPCG'ye Hoşgeldiniz ! Umarım burada iyi vakit geçirirsiniz.
Sızdıran Rahibe

1
@pbochinak Sanırım geçerli bir tane bulmuş olabilirim. f(6551)döner 25*8*9*7+9*8+(13 karakter) ise 9999***52*-(11 karakter) daha iyi bir tanesidir. evalYukarıdaki kendi işlevimle doğrulandı (soruda).
Sızdıran Rahibe

4
@pbochniak Madenden önceki yorumun işaret ettiği gibi, bu cevap mevcut durumunda geçersiz. Bir düzeltme üzerinde çalışırken geçici olarak silmeniz önerilir (başka bir şey değilse, aşağı oy çekmesini önlemek için).
Dennis

1
süre sadece olabilirwhile c:
Ven

Sen kullanabilirsiniz ;, en ven ucu (girintili bloklarda bayt kaydeder olan) değişkenlere ayrı atamaları için bir sembol ve her şeyden arasındaki boşluk kurtulmak ve tgidebilir.
CalculatorFeline

4

Perl, 134 133 132 128 bayt

İçin +5 içerir -Xlp(kod içerdiğinden 2 ekstra ')

STDIN'de hedef sayı ile çalıştırın:

perl -Xlp befour.pl <<< 123

befour.pl:

@1{1..9}=1..9;$.+=2,map{for$a(%1){"+-*/"=~s%.%"\$1{\$-=$a$&$_/'$1{$a}$1{$_}$&'=~/^.{$.}\$/}||=\$&"%eegr}}%1until$\=$1{$_}}{

Yapay sınırları yok ve kavramsal olarak biraz verimli ama yine de hızlandırmak için birkaç bayt feda etsem de korkunç çalışma süreleri var. Bir uzunluk 11 çözeltisi (örn. Hedef numarası 6551) oluşturmak sistemimde yaklaşık 5 saat sürer.

7 bayt daha feda etmek hızı biraz daha katlanılabilir hale getirir.

@1{1..9}=1..9;$.+=2,map{for$a(@a){"+-*/"=~s%.%"\$1{\$-=$a$&$_/'$1{$a}$1{$_}$&'=~/^.{$.}\$/}||=\$&"%eegr}}@a=keys%1until$\=$1{$_}}{

Uzunluk 11 çözeltisi için 17 dakika, uzunluk 13 çözeltisi için yaklaşık 5 saat. Uzunluk 15'e ihtiyaç duyan ilk sayı yaklaşık 2 gün süren 16622'dir. Uzunluk 17'ye ihtiyaç duyan ilk sayı 73319'dur.

Bölmenin 0'a doğru keserek bir tamsayı döndürdüğünü varsaydığına dikkat edin (befunge 93 belirtimi başına)


Dolar işaretleri ne yapar? (Perl hiç konuşmuyorum)
Leaky Nun

1
@KennyLau $skaler değere erişir. Çoğu dilde nereye yazabilirsiniz a=4, perl kullanır $a=4. Ancak daha karmaşık değişkenlerin skaler erişimi için de kullanılır. Örn $a{$b}, %a$b
hash'ten getirilir

2

Cı, 550 545 bayt

#define L strlen
#define y strcpy
#define t strcat
char c[9999][99];i=1,k=3;main(j){for(;i<10;i++)*c[i]=i+'0';for(;k--;){
for(i=1;i<9999;i++)for(j=1;j<=i;j++)*c[i]&&*c[j]&&(i+j>9998||*c[i+j]&&
L(c[i+j])<L(c[i])+L(c[j])+2||t(t(y(c[i+j],c[i]),c[j]),"+"),
i*j>9998||*c[i*j]&&L(c[i*j])<L(c[i])+L(c[j])+2||t(t(y(c[i*j],c[i]),c[j]),"*"));
for(i=9999;--i;)for(j=i;--j;)*c[i]&&*c[j]&&(*c[i/j]&&
L(c[i/j])<L(c[i])+L(c[j])+2||t(t(y(c[i/j],c[i]),c[j]),"/"),
*c[i-j]&&L(c[i-j])<L(c[i])+L(c[j])+2||t(t(y(c[i-j],c[i]),c[j]),"-"));}
scanf("%d",&i);printf("%s",c[i]);}

Gereksiz yeni satırları sildikten sonra 550 545 bayt (ön işleme yönergelerinden sonraki üç yeni satır hariç tümü).

@Kenny Lau - Giriş olarak 1 ile 9998 arasında bir tamsayı alabilir, ancak en uygun çözümün hesaplandığı girdi aralığının 9998'den daha küçük olduğunu düşünüyorum. Öte yandan, bellek her iki aralık genişletilebilir izin verir.

Program 9998'den daha yüksek bir sayıya yığının üzerine itemez. (9998 değiştirilebilir.) Programı farklı bir versiyonda çalıştırdım, herhangi bir sayı için iyileşme olduğu sürece dış döngü (k ile bir) üzerinde yineleme yaptım. 1 ile 9998 arasında (Dijkstra algoritmasında olduğu gibi). Üç iterasyondan sonra iyileşme olmaz. Baytları kurtarmak için k = 3 kodunu yazdım.

Aralığı genişletmek için iki şey gereklidir - 9999 ve 9998 sabitlerini değiştirmek, iyileştirme olduğu sürece çıkış döngüsü üzerinde değişken sayıda yineleme ile çalıştırmak, hiçbir gelişme gerçekleşmeyene kadar ne kadar sürdüğünü görmek için, k = 3 sabitini bu değere değiştirin.


PPCG'ye Hoşgeldiniz ! Umarım burada iyi vakit geçirirsiniz.
Sızdıran Rahibe

Bu, 6551 testimi mükemmel bir şekilde geçiyor. Bu programın etkili menzili nedir?
Sızdıran Rahibe

9999 olduğuna inanıyorum. Lütfen bu bilgiyi çözümünüze ekleyebilir misiniz?
Sızdıran Rahibe

Size başlatılıyor bazı bayt yiyebilir, ayrıca 9998. olmalı i, jve kdaha önce main().
Sızdıran Rahibe

1
@Kenny Lau - Düzenleme için teşekkür ederim. Aralığı genişletmek hakkında, aralığı genişletmek için biraz daha zaman gerektiğini fark ettim. Bu bilgiyi cevaba ekledim.
MissIbyte

2

Python 2, 284 bayt

Yasal Uyarı: Bazı değerler için sonsuza kadar korkutuyor ... ancak her zaman en kısa dizeyi döndüreceği garanti edilmelidir ve yapay olarak uygulanan aralık sınırı yoktur ... negatif değerler üzerinde bile çalışır. :)

def f(v):
 i,z=0,'+-*/'
 while 1:
  s=('%x'%i).translate(__import__('string').maketrans('abcd',z),'ef');t=s;q=[];a,p=q.append,q.pop;i+=1
  try:
   while t:
    o,t=t[0],t[1:]
    if o in z:n,m=p(),p();a(eval(`m`+o+`n`))
    else:a(int(o))
   if p()==v and not q:return s
  except:pass

Algoritma:

  • İle başla i = 0
  • Altıgen değerini temsil eden dize al i, ve değiştirme abcdile +-*/, sırasıyla, herhangi bir kaldırmaef
  • Dizeyi postfix gösterimi (RPN) olarak işlemeyi deneyin
  • Başarılıysa ve sonuç giriş değeriyle eşleşiyorsa, kullanılan dizeyi döndürün.
  • Aksi takdirde, artırın ive tekrar deneyin.

"[t] akes [...] sonsuza kadar bazı değerler için" Test ettiniz mi? Hangi değerler?
Leaky Nun

@KennyLau Sadece hesaplama oluyor bir test yazdı f(i)dan 0 <= i <= 6551(yakalamak için 6551sen 'in orijinal gönderme @pbochniak geçersiz kılmak için kullanılan değer). Şu anda, sadece birkaç dakikadır çalışıyor ve testin son çıktısı: 91 : 49+7* 3.020 s (total 108.174 s, worst 89: 5.827 s) Güncelleme - sadece 92 değeriyle bitti: 92 : 149+7*+ 258.761 s (total 366.935 s, worst 92: 258.761 s)
Ken 'Joey' Mosher

@KennyLau: Test bir saatten fazla sürdü ve sadece değere kadar 113... eğer ilgileniyorsanız tam test çıktısına bakın (pastebin) ...
Ken 'Joey' Mosher

2

Python 2, 182 bayt

n=input()
L=[[[],""]]
while 1:
 s,c=L.pop(0);L+=[[s+[i],c+`i`]for i in range(10)]+(s[1:]and[[s[:-2]+[eval(`s[-2]`+o+`s[-1]`)],c+o]for o in"/+-*"[s[-1]==0:]])
 if[n]==s[-1:]:print c;E

Çok yavaş, girişte bir saatliğine çalışmayı bıraktım 221ve hala sonlandırılmadı. Yavaşlık bir hayli Ben Genişlik öncelikli arama için bir sıra olarak bir liste kullanıyorum çünkü, ve .pop(0)olduğu O(n)listeler için.

Lyalnızca (stack, code to reach stack)çiftleri içeren bir kuyruktur. Her adımda her zaman rakamlar eklenir ve yığının en az iki öğesi varsa işleçler gerçekleştirilir. Bölme yalnızca son öğe 0 değilse gerçekleştirilir, ancak bölünmenin asla gerekli olmadığına dair güçlü bir şüphem olsa da (bunu kanıtlamanın hiçbir yolu olmamasına rağmen, ancak 500'e kadar olan durumun bu olduğunu kontrol ettim).

Program NameError, sonucu yazdırdıktan sonra (sonunda) sona erer .


Ne olduğunu ;Esonunda yapıyor?
Leaky Nun

@KennyLau Başka bir yerde tanımlanmadığından NameErrorbu fesih için E
geçerlidir

Vay be, çok zekice.
Leaky Nun


1

Pyth - 35 bayt

Kaba kuvvet. Bir garip şey yeni örtük girdi aslında olmasıdır acıyor bunun için çalışıyor görünüyor, çünkü benim puanı .vda pyth_eval.

.V1IKfqQ.x.v+jd_T\;N^s+"+-*/"UTbhKB

Burada çevrimiçi deneyin .


0

Python 3, 183 bayt

e,n=enumerate,input()
v=list('0123456789')+[' '*n]*n*2
for i,s in e(v):
 for j,t in e(v):
  for o,k in zip('+*-',(i+j,i*j,i-j)):
   if 9<k<2*n:v[k]=min(v[k],s+t+o,key=len)
print(v[n])

Hız tamamen mantıksız değil (123, 221, 1237, 6551 saniye veya dakika sırasıyla biter). Değişen ifiçin açıklama if j<=i and <k<2*no kadar fazla, 9 daha bayt pahasına hızlarda. ( /) Bölümünü dışarıda bıraktım , çünkü nasıl gerekli olacağını göremiyorum.


İpucu: bölme gereklidir.
Leaky Nun
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.