Yalnızca * 3 ve / 2 işlemlerini kullanarak 1 değerini herhangi bir pozitif tam sayıya dönüştürün


11

Herhangi bir pozitif tamsayı, 1 ile başlayıp her biri "3 ile çarp" veya "2 ile böl, kalanları atarak" işlem dizisi uygulanarak elde edilebilir .

Örnekler (* 3 için f ve / 2 için g yazma):

4 = 1 *3 *3 /2 = 1 ffg
6 = 1 ffggf = 1 fffgg
21 = 1 fffgfgfgggf

Aşağıdaki davranışa sahip bir program yazın:

Giriş : stdin veya sabit kodlu herhangi bir pozitif tamsayı. (Sabit kodlanmışsa, giriş sayısı program uzunluğundan hariç tutulur.)
Çıktı : f ve g dizisi ( <input> = 1 <string>örneklerde olduğu gibi). Böyle bir dize ters sırada da kabul edilebilir. Not: Çıktı yalnızca f ve g içerir veya boştur.

Kazanan, 41 girdi olduğunda program-artı-çıktısının en az baytına sahip olan girdidir.


1
Bunun doğru olduğunu nereden biliyorsun?
marinus

@marinus bunun doğru olduğuna inanılmaktadır (ancak henüz kanıtlanmamıştır). bir kanıt arıyor.
Fabinout

@marinus, iniş ile (veya güçlü indüksiyonla eşdeğer olarak) mümkün olduğunu kanıtlayabilirsiniz. Büyük / küçük harf bölünmesi x mod 3: eğer x=3yy yapısı ve sonra uygulanır f; eğer x=3y+1yapı 2y+1ve uygulamak fardından g; eğer x=3y+2o zaman karmaşık ama aslında özyinelemelidir alır.
Peter Taylor

Ayrı bir notta, çıktı uygulama sırasında olmalı mı yoksa kompozisyon sırası da kabul edilebilir mi?
Peter Taylor

@PeterTaylor Her iki durumda da sorun yok.
res

Yanıtlar:


3

GolfScript, puan 64 (43-2 + 23)

0{)1.$2base:s{{3*}{2/}if}/41=!}do;s{103^}%+

(41 kodlanmış, bu nedenle skor için -2 karakter). Çıktı

fffgffggffggffgggffgggg

23 karakterdir (satırsonu olmadan). Yapım gereği, kod her zaman en kısa temsillerden birini döndürdüğünü garanti eder.


Kullanıcı aktaran Darren Stone içinde önerilen bir düzenleme bu yayında: ".. Ben bir düzenlemeyi bırakacak işte Yorum bırakmak alamıyorum Bu çıkış, ilk iki karakter içermez '1' ne de skora yansıdı olanlardır bir olmalı kolay düzeltme ve hala inanılmaz kısa bir çözüm. Şerefe! " (Reddettim, ama mesajı
taşımam

@Doorknob Zorluk "1 ", çıktıya dahil edilmemesi gerektiğini belirtir .
Howard

3

Kirleniyoruz arkadaşlar!

JAVA 210 207 199 karakter

public class C{public static void main(String[] a){int i=41;String s="";while(i>1){if(i%3<1){s+="f";i/=3;}else if(i%3<2){s+="g";i+=i+1;}else{s+="g";i+=i+(Math.random()+0.5);}}System.out.println(s);}}

olmayan golfed:

public class C {

    public static void main(String[] a) {

        int i = 41;
        String s = "";
        while (i > 1) {
            if (i % 3 == 0) {
                s += "f";
                i /= 3;
            } else {
                if (i % 3 == 1) {
                    s += "g";
                    i += i + 1;
                } else {
                    s += "g";
                    i += i + (Math.random() + 0.5);
                }
            }
        }
        System.out.println(s);
    }
}

çıktı: Eski tanrıların inancına bağlı olarak, sahip olduğum en kısa süre 30'du. Çıktının sağdan okunması gerektiğini unutmayın.

234

1 ggfgfgfgfggfggfgffgfggggfgffgfggfgfggggfgffgfggfgfggfgfggfgfgggggfffgfggfgfggfgfgggffgggggfffgfggggfgffgfggfgfggfgfggfgfggfgfggfgfggfgfggggfgffgfggfgfggfgfggfgfggfgfggfgfggggggggggggfgfgfggggfgfgfggfffgfgfggffgfgfggfgfggggffgfgfffff

108

1 gggffgfgfggggggfggggfgffggggfgfgfgfgfgffgggfgggggfggfffggfgfffffgggffggfgfgggffggfgfgggffggggggfgfgffgfgfff

düzenle 45

1 ggfgfgfgfgggfggfffgfggfgfgggggggffgffgfgfff

puan: 318 199 + 30 = 229

edit1 (2 * i + 1)% 3 == 0 -> (2 * i)% 3 == 1

Golf yaparken Java 7 değil, Java 6 kullanıyorsanız, Nota Bene,

public class NoMain {
    static {
        //some code
        System.exit(1);
    }
}

53 karakter uzunluğunda standart yapı yerine 39 karakterlik yapı.


(2*i+1)%3==0ile eşdeğeri%3==1
Howard

Evet öyle. teşekkürler
Fabinout

if(X){A}else{if(Y){B}else{C}}daha uzun if(X){A}else if(Y){B}else{C}. Ayrıca ==koşullarınızı daha kısa <koşullarla değiştirebilirsiniz .
Peter Taylor

@PeterTaylor doğru, benim çözüm hala çirkin. Rastgele bölüm kodu kısaltır mı bilmiyorum, ama sures çıkış daha dar yapar.
Fabinout

F / g dizeleriniz 'g' ile başlar ('/ 2' anlamına gelir), bu nedenle 41 yerine 1'e 0 dönüştürürler. F'leri g'lere ve tersine değiştirmek de 41.
res

3

Python, skor 124 (90-2 + ​​36)

x=41;m=f=g=0
while(3**f!=x)*(m!=x):
 f+=1;m=3**f;g=0
 while m>x:m/=2;g+=1
print'f'*f+'g'*g

90 karakter kodu (her biri 1 satırda yeni satırlar) - sabit kodlu giriş sayısı için 2 + 36 karakter çıkışı

Çıktı:

ffffffffffffffffgggggggggggggggggggg

1
Bunu yaparsanız m=f=0, dış döngüyü yapabilir while(n!=x)*(m!=x)ve araları kaldırabilirsiniz. 95 karakter koduna getirir.
Daniel Lubarov

@Daniel: Siz, efendim, bir beyefendi ve bilginsiniz. Teşekkürler! Gönderiminiz hala güvenli bir şekilde 10 karakter önümde. :)
Darren Stone

1
Eğer hepsini yerine eğer biraz daha kaydedebilirsiniz ntarafından 3**f.
Howard

1
İnput = 1 için, programınız bir hata üretir (dış while döngüsüne girmemesi nedeniyle "name 'g' tanımlı değil").
res

1
Yazarak başka bir karakteri kesebilirsiniz print'f'*f+'g'*g, bu da 90-2 + ​​36 = 124 puan verir.
res

3

Python, skor 121 (87-2 + 36)

t=bin(41)
l,n,f=len(t),1,0
while bin(n)[:l]!=t:f+=1;n*=3
print(len(bin(n))-l)*'g'+f*'f'

@Darren, çıktı açıklamasını nasıl yorumlayacağından emin değildim, ama muhtemelen haklısın. '1'i ekledim. Teşekkürler!
Daniel Lubarov

1
'1'i bırakabilirsiniz (tekrar!) Çıktı tanımının orijinal yorumu doğru. Yine Python'un tadını çıkarın! :-)
Darren Stone

1
Eğer 2., 3., ve içine 4 çizgileri kombine olursa l,n,f=len(t),1,0ve kaldırılan '1',baskı ekstrenizden, puanınız 87-2 + 36 = 121. olurdu
res

Teşekkürler çocuklar - düşürdüm 1,. l,n,f=len(t),1,0aynı sayıda karakter veriyor, değil mi? (Her değişken için bir =ve bir yeni satır iki ,s ile değiştirilir .)
Daniel Lubarov

Her yeni satır bir karakter ise (örneğin UNIX stili LF), tek satır ve üç satır sürümleri aynı uzunlukta olur. Her yeni satır iki karakterden oluşuyorsa (örneğin, MS Windows tarzı CR + LF), tek satırlı sürüm üç satırlı sürümden iki karakter daha kısadır. 121 puanı tek karakterlik yeni satırlar alır.
res

1

Perl, skor 89 (63-2 + 28)

$_=41;$_=${$g=$_%3||$_==21?g:f}?$_*2+$_%3%2:$_/3while$_>print$g

Sonuç: Aşağıdaki orijinal çözümümde anlatılan saf yaklaşım bir döngüye ulaşırsa, bu döngü [21, 7, 15, 5, 10, 21, ...] olacaktır . 1 ≤ n ≤ 10 6 için karşı örnek olmadığından, bu muhtemelen doğru görünmektedir. Bunu kanıtlamak için, bu tek döngü olduğunu göstermeye yeterli olacaktır edebilirsiniz I veya zaman içinde daha sonraki bir noktada yapmak olmayabilir var.

Yukarıdaki çözüm, (yanlış) tahmin etmek ve ikinci kez kaçmak yerine, döngüyü hemen önler.

Çıktı (28 bayt):

ggfgfgfgfggfggfgfgfggfgfgfff

Perl, puan 100 (69-2 + 33)

$_=41;1while$_>print$s{$_=$$g?$_*2+$_%3%2:$_/3}=$g=$_%3||$s{$_/3}?g:f

Tahmin ve kontrol yaklaşımını kullanarak. Dize, ters işlemler kullanılarak oluşturulur ( başka bir yol yerine değeri 1'e dönüştürülür ) ve dize, sorun belirtimi tarafından izin verilen şekilde buna göre yansıtılır.

Üçten çoğuyla karşılaşılmadığında, sonuç ikiyle çarpılır ve sonuç üçün katı olacaksa bir tane eklenir. Üçten bir katıyla karşılaşıldığında, üçe bölünecektir ... bu değere daha önce rastlanmadıkça, bir döngüyü, dolayısıyla tahmin et ve kontrol et.

Çıktı (33 bayt):

ggfgfgfgfggfggfgffgfgggfggfgfgfff

1

J, puan 103 (82-2 + 23)

* Not: Ben fiiller adında fve gçıkış dizeleri ile karıştırılmamalıdır, fve g.

Sabit kodlanmış:

f=:3 :'s=.1 for_a.y do.s=.((<.&-:)`(*&3)@.a)s end.'
'gf'{~#:(>:^:(41&~:@f@#:)^:_)1

Genel fonksiyonlar:

f=:3 :'s=.1 for_a.y do.s=.((<.&-:)`(*&3)@.a)s end.'
g=:3 :'''gf''{~#:(>:^:(y&~:@f@#:)^:_)1'

Sıkıştırma açısından en önemli değişiklik olan ikili sayı blokları üzerinde çalışarak ortadan kalktı g. Değişkenler yeniden adlandırıldı ve bunun için bazı boşluklar kaldırıldı, ancak her şey hala işlevsel olarak aynı. (Kullanım: g 41)

J, puan 197 (174 + 23)

f =: 3 : 0
acc =. 1
for_a. y do. acc =. ((*&3)`(<.&-:)@.a) acc end.
)

g =: 3 : 0
f2 =: f"1 f.
l =. 0$0
i =. 1
while. 0=$(l=.(#~(y&=@:f2))#:i.2^i) do. i=.>:i end.
'fg'{~{.l
)

Çıktı: ffffffffggggggggfgffggg

fbooleans listesini 0s as *3ve 1s /2(ve floor) kullanarak sayıya dönüştürür . #:i.2^itüm rank 1 boolean uzunluk dizilerini içeren bir rank 2 dizisi oluşturur i.

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.