Numaraları değiştirme [kapalı]


10

Bu, çoğunuz elle çözdüğünüz ortak bir bilmecedir. Şimdi bu sorunu çözmek için bir algoritma yazma zamanı.

Birbirlerinin yönüne bakan iki farklı tarafa dizilmiş eşit sayıda maç çubukları vardır. Aralarında tek bir boşluk var. Aşağıdaki şekle benzer bir şey söyleyin (toplam maç sopa sayısı 4 ise).

resim açıklamasını buraya girin

Her çubuk ya bir adım ileri yönde kayabilir (hemen ön alan boşsa) veya önlerindeki bir çubuğun üzerinden atlanabilir ve boş alana inebilir (bu alan boşsa). Ters yönde hareket mümkün değildir (boşluk bile olsa). Ters atlamaya da izin verilmez. Bir adımda yalnızca bir hamleye izin verilir.

Şimdi, tüm sol taraftaki maç sopalarının sağ tarafa ineceği ve tüm sağ taraftaki maç sopalarının sol tarafa ineceği gereken minimum adımları bulmak için bir algoritma yazmalısınız.

Örneğin: Toplam 2 maç çubuğu (her iki tarafta 1 adet) varsa, adımlar şu şekilde olacaktır:

resim açıklamasını buraya girin

Not: Yukarıdaki şekilde ilk önce sol taraftaki çubuk hareket ettirilmiştir. Sağ taraftaki çubuk ilk hareket ettiğinde başka bir çözüm daha vardır. Ancak bu sorun için sadece bir çözüm vermelisiniz ve bu da sol taraftaki çubuğun önce hareket ettiğini varsayar.

Aşağıdaki şekilde 4 kibrit çubuklu (her iki tarafta 2 adet) hareket açıklanmaktadır:

resim açıklamasını buraya girin

Not: Yukarıdaki şekilde ilk önce sol taraftaki çubuk hareket ettirilmiştir. Sağ taraftaki çubuk ilk hareket ettiğinde başka bir çözüm daha vardır. Ancak bu sorun için sadece bir çözüm vermelisiniz ve bu da sol taraftaki çubuğun önce hareket ettiğini varsayar.

[Varsayım: Giriş 02 ila 14 arasında herhangi bir çift sayı olabilir (yani her bir tarafta 1 ila 7 eşleşme çubuğu). Bu aralığın dışındaki girişler için herhangi bir doğrulama yapmanız veya hata mesajı vermeniz gerekmez. Not: Çıktıda, her adım bir '|' ile ayrılır karakter. COBOL programcıları her zaman giriş boyutu olarak PIC 9 (2) varsaymalı ve çıktının sağda boşluklarla doldurulmuş maksimum uzunluk 450 karakter olarak sabit olduğunu varsayabilir.]


Örnek Giriş:

02  

Örnek Çıktı:

01To02|03To01|02To03|


Örnek Giriş:

04  

Örnek Çıktı:

02To03|04To02|05To04|03To05|01To03|02To01|04To02|03To04|


Örnek Giriş:

06  

Örnek Çıktı:

03To04|05To03|06To05|04To06|02To04|01To02|03To01|05To03|07To05|06To07|04To06|02To04|03To02|05To03|04To05|

Görüntüleri doğrudan ekleyemiyorsanız, başkasının bunları düzenlemesi için bağlantılar sağlayabilir misiniz?
Peter Taylor

2
Bazı hızlı görüntüler yaptım. Umarım orijinal yazarın niyetine uyarlar.
primo

3
Zafer koşulu mu?
Shmiddty

Yanıtlar:


3

APL 129

Aşağıdaki kod, ekran girişini ve çıkışlarını belirtilen biçimde ekrana alır:

n←n,n++\1↓z←(⌽z),((¯1*~2|n)×n⍴2),z←⌽∊(¯1*2|⍳n)ר1,((⍳(n←.5×⍎⍞)-1)⍴¨2),¨1⋄(∊(((¯2↑¨'0',¨⍕¨n),¨⊂'To'),¨(¯2↑¨'0',¨⍕¨n-z)),¨⊂'|')~' '

Kodun iyi bir üçte biri çıktı biçimlendirilir. Mantık kodda ⋄ sembolünün oluşmasıyla tamamlanır.

Aşağıda, kontrol olarak 08 girdisinin sonucu verilmiştir:

04To05|06To04|07To06|05To07|03To05|02To03|04To02|06To04|08To06|09To08|07To09|05To07|03To05|01To03|02To01|04To02|06To04|08To06|07To08|05To07|03To05|04To03|06To04|05To06|

1
Hep APL aldatıyor gibi hissediyorum. <
Shmiddty

@Shmiddty APL, J, GolfScript vb.Gibi herhangi bir sembol tabanlı dilin büyük olasılıkla daha ayrıntılı kelime tabanlı dillere karşı kod golf kazanacağından korkuyorum;)
Graham

3

JavaScript 178 174 161

promptiçin s nsonra alerts cevap. ( 0Dolgu yok )

En son:

t=1+(m=prompt(s=i='')/2);for(z=Math.abs;i++<m*2;)for(j=m-z(m-i),s+=(t+=a=(m%2^z(m+.5-i)%2-.5)*-2+1)+'To'+(t-a)+'|';j--;)s+=(t+=a=i%2*4-2)+'To'+(t-a)+'|';alert(s)

2:

z=Math.abs;t=m=prompt(o=[])/2;t++;for(s=i='';i++<m*2;)for(j=m-z(m-i),o.push((z(m+.5-i)%2-.5)?-1:1);j--;)o.push(i%2?2:-2);o.map(function(a){s+=(t+=a)+'To'+(t-a)+'|'});alert(s)

1:

t=m=prompt(o=[])/2+1;for(s=i='';++i<m;)for(j=i,o.push(i%2?-1:1);j--;)o.push(i%2?2:-2);o.concat(o.slice().reverse().slice(m-1)).map(function(a){s+=(t+=a)+'To'+(t-a)+'|'});alert(s)

Bu, desenin yansıtıldığı kavramını kullanır:

Key
R='Jump Right'
r='Shift Right'
L='Jump Left'
l='Shift Left'
m='Move'
j='Jump'

Yani, n=2hareketin paterni:

rLr
mjm

Hangi eşittir

+1 -2 +1

Bu desen böyle tekrar eder ( n=8)

rLlRRrLLLlRRRRlLLLrRRlLr
mjmjjmjjjmjjjjmjjjmjjmjm
+1 -2 -1 +2 +2 +1 -2 -2 -2 -1 +2 +2 +2 +2 -1 -2 -2 -2 +1 +2 +2 -1 -2 +1

Burada birkaç örüntü fark edebiliriz:

  1. Hareket sol ve sağ arasında değişir
  2. Belirli bir yöndeki hareket sayısı 1'den artar n/2, bu da 3 kez tekrarlanır, daha sonra 1'e düşer.
  3. Hareket türü, kaydırma ve atlama arasında değişir, bir satırdaki kayma sayısı sabittir 1ve ardışık sıçrama sayısı 1'den artarak 1'e n/2düşer.
  4. Hareketlerin toplamı her zaman 0'dır. (Bunun gerçekten alakalı olup olmadığından emin değilim)

n=14:

rLlRRrLLLlRRRRrLLLLLlRRRRRRrLLLLLLLrRRRRRRlLLLLLrRRRRlLLLrRRlLr
mjmjjmjjjmjjjjmjjjjjmjjjjjjmjjjjjjjmjjjjjjmjjjjjmjjjjmjjjmjjmjm

Örnek çıktı:

f(2):

1To2|3To1|2To3| 

f(8):

4To5|6To4|7To6|5To7|3To5|2To3|4To2|6To4|8To6|9To8|7To9|5To7|3To5|1To3|2To1|4To2|6To4|8To6|7To8|5To7|3To5|4To3|6To4|5To6|

f(40):

20To21|22To20|23To22|21To23|19To21|18To19|20To18|22To20|24To22|25To24|23To25|21To23|19To21|17To19|16To17|18To16|20To18|22To20|24To22|26To24|27To26|25To27|23To25|21To23|19To21|17To19|15To17|14To15|16To14|18To16|20To18|22To20|24To22|26To24|28To26|29To28|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|12To13|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|31To30|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|10To11|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|33To32|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|8To9|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|35To34|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|6To7|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|37To36|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|4To5|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|39To38|37To39|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|3To5|2To3|4To2|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|40To38|41To40|39To41|37To39|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|3To5|1To3|2To1|4To2|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|40To38|39To40|37To39|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|3To5|4To3|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|37To38|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|6To5|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|35To36|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|8To7|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|33To34|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|10To9|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|31To32|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|12To11|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|29To30|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|14To13|16To14|18To16|20To18|22To20|24To22|26To24|28To26|27To28|25To27|23To25|21To23|19To21|17To19|15To17|16To15|18To16|20To18|22To20|24To22|26To24|25To26|23To25|21To23|19To21|17To19|18To17|20To18|22To20|24To22|23To24|21To23|19To21|20To19|22To20|21To22|

İşte yöntemi göstermek için bazı sözde kod:

var mid=cursor=N/2,delta
cursor++                 // the cursor is where the empty space is.
for(i=0; i++<N;){
  delta = (mid%2^abs(mid+.5-i)%2-.5)*-2+1;  // 1 or -1
  print((cursor+delta) + 'To' + cursor + '|')
  cursor+=delta
  for(j=mid-abs(mid-i);j--;)
  {
    delta = i%2*4-2  // 2 or -2
    print((cursor+delta) + 'To' + cursor + '|')
    cursor+=delta
  }
}

2
Sen desen ile daha açıktır doğru olduğunu konum l/L/r/Rve m/j. Yönünden taşınan mesafeyi ayırma fikrini seviyorum
Gordon Bailey

2

C - 216 213

Benim çözümüm iki gerçeğe dayanıyor:

  1. "Kime" alanı, önceki hareketin "kime" alanıdır (çünkü her zaman hareket ettiğiniz alanda boş bir yuva oluşturduğunuzdan ve her zaman boş bir yuvaya geçtiğinizden)

  2. Taşınan mesafeler ve yönler için çok düzenli bir düzen vardır. İlk 3 test vakası için bunlar:

    1 -2 1

    1 -2 -1 2 2 -1 -2 1

    1 -2 -1 2 2 1 -2 -2 -2 1 2 2 -1 -2 1

Bunu göz önünde bulundurarak temelde bu kalıbı üretmek ve devam ettirmek için bir program yazdım. Bunu yazmak için gerçekten güzel ve çok daha zarif bir özyinelemeli yol olması gerektiğinden eminim, ancak henüz çözemedim:

#include <stdio.h>

int main(int argc, const char *argv[])
{
   int upper_bound = atoi(argv[1]) / 2;
   int len;
   int from;
   int to = upper_bound + 1;
   int direction = 1;
   int i;

   for(len = 1; len <= upper_bound; ++len){
      for(i = len-1; i >=0; --i){
         from = to - direction*(1 + (i!=0));
         printf("%02dTo%02d|",from,to);
         to = from;
      }
      direction*=-1;
   }
   for(i=1; i < len; ++i){
      from = to - direction*2;
      printf("%02dTo%02d|",from,to);
      to = from;
   }
   direction*=-1;
   for(--len; len >= 0; --len){
      for(i = 0; i < len; ++i){
         from = to - direction*(1 + (i!=0));
         printf("%02dTo%02d|",from,to);
         to = from;
      }
      direction*=-1;
   }
   return 0;
}

Ve golf (bu golf değil, bir kod meydan okuma olmasına rağmen):

#define B {F=T-D*(1+(i!=0));printf("%02dTo%02d|",F,T);T=F;}D*=-1;
L,F,T,D,i;main(int U,char**A){U=atoi(A[1])/2;T=U+1;D=1;for(L=1;L<=U;++L){for(i=L-1;i>=0;--i)B}for(i=1;i<L;++i)B for(--L;L>=0;--L){for(i=0;i<L;++i)B}}

#define B {F=T-D*(1+(i!=0));printf("%02dTo%02d|",F,T);T=F;}D*=-1;
L,F,T,D,i;main(int U){scanf("%d",&U);U/=2;T=U+1;D=1;for(L=1;L<=U;++L){for(i=L-1;i>=0;--i)B}for(i=1;i<L;++i)B for(--L;L>=0;--L){for(i=0;i<L;++i)B}}

Golf versiyonunu çalıştırdığımda bir segfault alıyorum.
artistoex

Oh üzgünüm, girişin bir komut satırı argümanı olarak verildiğini söylemeyi unuttum - eğer argüman olmadan çalıştırırsanız segfault olur. Ama aslında bundan bahsettiğinize göre, komut satırı argümanlarının neden daha kısa olacağını düşündüğümü bilmiyorum scanf. Cevabımı daha iyi bir sürümle güncelliyoruz.
Gordon Bailey

: Eğer L / R / l / r (büyük varlık "sıçrama") kullanırken model daha belirgindir N(2)=rLr, N(4)=rLlRRlLr, N(6)=rLlRRrLLLrRRlLrvb
Shmiddty

2

Mathematica

Bu yaklaşım, bir inşa Nestolarak biçimlendirilmiş hamle, büyüklüğü ve yönü ed sekansı {fromPosition,toPosition}pozisyon ile başlayan n, nçift maç sayısını ifade eder. Daha sonra Foldhareket ile başlayan bir işleve dizidir {n, n+1}.

z@n_:=(p=1;h@t_:=Append[{Table[2 (-1)^t,{t}]},{(-1)^(t+1)}];
k=Join[Reverse@Drop[#,n],#]&[Flatten@Nest[Prepend[#,h[p++]]&,{},n]];
Fold[Append[#,{#[[-1,1]]-#2,#[[-1,1]]}]&,{{n,n+k[[1]]}},Rest@k])

z[1]

{{1, 2}, {3, 1}, {2, 3}}


z[4]

{{4, 5}, {6, 4}, {7, 6}, {5, 7}, {3, 5}, {2, 3}, {4, 2}, {6, 4}, { 8, 6}, {9, 8}, {7, 9}, {5, 7}, {3, 5}, {1, 3}, {2, 1}, {4, 2}, {6, 4}, {8, 6}, {7, 8}, {5, 7}, {3, 5}, {4, 3}, {6, 4}, {5, 6}}


z[7]

{{7, 8}, {9, 7}, {10, 9}, {8, 10}, {6, 8}, {5, 6}, {7, 5}, {9, 7}, { 11, 9}, {12, 11}, {10,12}, {8, 10}, {6, 8}, {4, 6}, {3, 4}, {5, 3}, {7, 5}, {9, 7}, {11, 9}, {13, 11}, {14, 13}, {12, 14}, {10, 12}, {8, 10}, {6, 8} , {4, 6}, {2, 4}, {1, 2}, {3, 1}, {5, 3}, {7, 5}, {9, 7}, {11, 9}, { 13, 11}, {15, 13}, {14, 15}, {12, 14}, {10, 12}, {8, 10}, {6, 8}, {4, 6}, {2, 4}, {3, 2}, {5, 3}, {7, 5}, {9, 7}, {11, 9}, {13, 11}, {12, 13}, {10, 12} , {8, 10}, {6, 8}, {4, 6}, {5, 4}, {7, 5}, {9, 7}, {11, 9}, {10, 11}, { 8, 10}, {6, 8}, {7, 6}, {9, 7}, {8, 9}}


Swapları Görselleştirme

r,, bve osırasıyla resimler veya kırmızı eşleşme, mavi eşleşme ve eşleşme yok.

maçlar

Aşağıdakiler, çıktıları zeşleşmelerle gösterecek şekilde biçimlendirir .

swaps[n_]:=FoldList[Grid[{Permute[#[[1,1]],Cycles[{#2}]],Range[2n+1]}]&,
Grid[{Join[Table[r,{n}],{o},Table[b,{n}]],Range[2n+1]}],z[n]]

swapMatches[n_]:=Grid[Partition[swaps[n],2,2,1,""],Dividers->All]

swapszilk listeye ve sonraki listelere izin vermek için sıralı as komutlarını kullanarak bir durum listesi oluşturur .

swaps[1]

swaps1

swapMatches durumları bir ızgarada görüntüler.

swapMatches[2]

swaps2

swapMatches[3]

swaps3


0

Javascript 191

function f(N) {
    n=N>>=i=c=a='1';n++
    s=z='0'
    for(k=b='34';i<N;k=i%2?a+=z+z:b+='44',i++)c=k+c
    t=''
    i=N*(N+1)/2
    l=2*i+N
    for(;l;n+=(i>=1?r=c[i-1]:i<=-N?c[-i-N]:k[1])-2,t+=(s=n>9?'':z)+n+a+'|',--l,--i)a='To'+s+n
    return t
}

Kullanılarak sayılan karakterler grep =|tr -d \ |wc -c


1
Merhaba ve codegolf'a hoş geldiniz! Çözümünüzün test durumlarının hiçbiri için doğru çıktıyı sağlamadığını göreceksiniz ( jsfiddle.net/SJwaU ). Giriş 02için değerler doğrudur, ancak sondaki nokta eksik |. Diğer iki durumda, değerler yol dışıdır ve biçimlendirmesi 10de yanlıştır. Ayrıca karakter sayma yönteminizden de emin değilim. Neden sadece fonksiyon gövdesini geri dönüş eksi olarak sayıyorsunuz?
Gordon Bailey

@gordon Hata! En son optimizasyonumda bir hata yapmışım gibi görünüyor. İşaret ettiğiniz için teşekkürler. Vücudu sadece bir REPL'de saydığım için ihtiyacım var. Fonksiyon dekorasyonunu sadece kolaylık sağlamak için koydum.
artistoex

Toplamınıza doğru alakalı boşluk (örn. Yeni satırlar) saymanız gerekir.
Shmiddty

@shmiddty tr -d \ |wc -cyeni satırları dikkate alıyor
artistoex
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.