Tatil Hediye Alışverişi


11

Bizim iç golf başka bir sorun ... bu geçen yıl tatil etrafında.

SORUN

Andy, Barb, Carl, Didi, Earl ve Fran birbirlerine hediyeler alıyorlar. Bir hediye alışverişi için isimler çizin.

  1. Her kişi bir hediye alır ve bir hediye alır.
  2. Kimse kendi armağanını almaz.
  3. Çözümü birden çok kez çalıştırmak farklı sonuçlar üretmelidir (verici-alıcı çifti öngörülememeli veya çalışmadan çalışmaya aynı olmamalıdır).

GİRİŞ

Yok.

ÇIKTI

Bu örnekteki gibi biçimlendirilmiş:

Andy
Barb için satın alır Barb
Carl için satın alır Carl
Didi için satın alır Didi
Earl için satın alır Earl için
Fran satın alır Fran için Andy satın alır


Çıktı isme göre sıralanmalı mı?
Eelvex

@Eelvex Hayır, gerekli değil.
Steve

1
Bu, bugün bir soru ile çoğaltıldı ve aradığım anahtar kelime bu soruyu açmadı, bu nedenle gelecekteki aramalar için: düzensizlik.
Peter Taylor

Yanıtlar:


4

J, 57

(,.' buys for ',"1|.)(?~6){6 4$'AndyBarbCarlDidiEarlFran'

Örneğin

   (,.' buys for ',"1|.)(?~6){6 4$'AndyBarbCarlDidiEarlFran'
Carl buys for Earl
Andy buys for Barb
Fran buys for Didi
Didi buys for Fran
Barb buys for Andy
Earl buys for Carl

[J] bilmiyorum, ama isimler farklı uzunluklarda olsaydı bu işe yarar mı?
16:14

Hayır. Kod, tüm adların 4 karakter uzunluğunda olmasından yararlanır. Çok az değişiklikle farklı uzunluklarda çalışacaktır.
Eelvex

Bu aynı zamanda çift sayıda insanın varlığından yararlanır. X, Y'ye verirse, Y'nin her zaman X'e de vereceğini unutmayın.
Adám

3

c99 - 252 karakter

#include <stdio.h>
#define G for(i=0;i<6;i++)
char*n="Andy\0Barb\0Carl\0Didi\0Earl\0Fran",*p[7];int i,j;int main()
{FILE*r=fopen("/dev/random","r");G p[i]=n+5*i;G{j=fgetc(r)%6;p[7]=p[j]
;p[j]=p[i];p[i]=p[7];}G printf("%s buys for %s\n",p[i],p[(i+1)%6]);}

Permütasyonun dairesel doğasından yararlanarak hafif iyileşme. Bu sürüm her zaman döngü benzeri bir satın alma stratejisi oluşturur, bu nedenle önceki (271 karakter) sürümden daha az rastgele, ancak yine de spesifikasyonu karşıladığına inanıyorum.

Çalışan bir platform gerektirir /dev/random. Ben \0büyük dize s atlayarak yaklaşık 8 kapalı vurmak gerekir , ama benim libc %4sadam sayfanın dediği gibi baskı belirteçleri ile uğraşmak gibi görünmüyor .

Karıştırma kötü, ama bu şekilde yapmak "Foo satın almak için Foo satın alma" koşullarını kontrol etmemi engelliyor .

Okunabilir:

#include <stdio.h>

char *n="Andy\0Barb\0Carl\0Didi\0Earl\0Fran",
  *p[7]; /* 7th cell for temp */
int i,j;

int main(){
  FILE*r=fopen("/dev/random","r");
  for(i=0;i<6;i++)
    p[i]=n+5*i;   /* Initialize the pointers */
  for(i=0;i<6;i++){
    j=fgetc(r)%6; /* Poor numeric properties. Cest le Code Golf */
    p[7]=p[j];
    p[j]=p[i];
    p[i]=p[7];
  }
  for(i=0;i<6;i++)
    printf("%s buys for %s\n",p[i],p[(i+1)%6]);
}

3

Windows PowerShell, 83

$i=random 5
($n=-split'Andy Barb Carl Didi Earl Fran')|%{"$_ buys for "+$n[++$i%6]}

Tarih:

  • 2011-02-11 22:01 (136) - İlk deneme.
  • 2011-02-11 22:05 (130) - Birkaç şeyi çizdi. Dizinleri değil, şimdi adları karıştırmak.
  • 2011-02-13 16:13 (128) - $iHer seferinde yeniden yaratılacağı gibi modüle ihtiyacım yok .
  • 2011-02-13 16:20    (87) - Anon'dan fikir ödünç aldı . s' , C # çözeltisi . Sadece rastgele bir ofset oluşturun ve sonra çevrelerinde hediye etmelerine izin verin.
  • 2011-02-13 16:26    (83) - Değişen rasgele sayı üretimi ve indeksleme. $_Kaydetmek için dizeye çekti +.

3

Haskell, 241189 karakter

import Data.List
import Random
main=randomRIO(0,719)>>=mapM_ putStrLn.f
f n=map(\(x,y)->x++" buys for "++y).zip(l n).tail$cycle$l n
l=(permutations(words"Andy Barb Carl Didi Earl Fran")!!)

Tamamen rastgele çıktı (hala özellikleri karşılar).

Bu, adlar listesinin tüm permütasyonlarını üretir, rastgele birini seçer ( Sanırım bu, listeyi karıştırmanın Haskell'deki en kısa yoludur - eğer daha küçük bir şey varsa, bunu takdir ederim) ve sonra her kişi bir listedeki bir sonraki kişi için hediye.


Bu ad- hoc'u
FUZxxl

@Anon: permutations$words"Andy Barb Carl Didi Earl Fran"ve geliştirilmiş versiyonumda denediğim diğer numaralar. Unuttum, bu permutations98'e dahil değil List, bu yüzden uzun adı da kullanmalısınız. Şuna bir göz at.
FUZxxl

Ve özel bir amaç için: r=tail.cycle. ve satır içi.
FUZxxl

202 karaktere indirdim . Bir göz atın: paste.ubuntuusers.de/399799
FUZxxl

1
Ve 189 karakter için, main=randomRIO(0,719)>>=mapM_ putStrLn.f
örneğimdeki

3

Golfscript: 72 64 57 karakter

"AndyBarbCarlDidiEarlFran"4/{;9rand}${.n+\' buys for '}%(

Testler

$ golfscript codegolf-838.gs 
Fran buys for Carl
Carl buys for Andy
Andy buys for Barb
Barb buys for Didi
Didi buys for Earl
Earl buys for Fran

$ golfscript codegolf-838.gs 
Didi buys for Earl
Earl buys for Andy
Andy buys for Barb
Barb buys for Carl
Carl buys for Fran
Fran buys for Didi
  • İçin teşekkürler gnibbler "AndyBarbCarlDidiEarlFran"4/, güncellendi ve 7 karakter daha az var
  • 57 chars çözümü temelde Nabb: D'dir ve aynı zamanda ;9randbenim6rand*

1
"AndyBarbCarlDidiEarlFran"4/
gnibbler

ah ha, teşekkürler @gnibbler, havalı, güncelleyeceksin.
SİZ

Neden kullandığınızdan emin değilsiniz 6rand*- 0=randya da belki ;9randde tercih edilebilir. Döngü {.n+\' buys for '}%(için daha kısa ..
Nabb

hah; şimdi J ile aynı karakter sayısı oldu: D ve teşekkür ederim @ Nabb, ben 6rand*6 ürün dizisini eşit olarak rastgele olacağını düşündüm çünkü kullandım (benden yanlış olduğunu düşünüyorum, çünkü ;9randbenden gerçekten rastgele görünüyor çünkü )
SİZE

3

Japt -R, 41 bayt

`AÌ)B¼C¤E¤FÎÂDi¹`qe ö¬ê1 ò mq` ¿ys f 

@Oliver sayesinde -2 bayt!

Dene!

Yüksek düzeyde benimsediğim yaklaşım bu:

  • katılımcı adlarını içeren bir dizgenin sıkıştırmasını açma
  • dizeyi bir diziye böl
  • karıştır
  • her bir kişiyi bir sonraki en yüksek endekse sahip kişiye atayın
  • dizideki son kişi ilk kişiye atanır

Yıllar önce işim için bir "gizli santa" programı hazırladığım için bu problemle ilgili küçük bir geçmişim var. Sonunda birkaç iş başvurusunda bulunanın da üzerinde çalışmasını istedik :)


@Oliver - ipuçları için teşekkürler! ãİlk öğeyi son öğeye bağlayan bir çift döndürmüyor gibi görünüyor . Ben bu işe yarayacak bir yol üzerinde çalışıyorum, ama size bildirir düşündüm. Yine teşekkürler! ethproductions.github.io/japt/…
dana

43 ?
dana



Ne bekle "q"de .ö("q")do
ASCII sadece

2

Python - 118 karakter

from random import*;L="Andy Barb Carl Didi Earl Fran".split()
for i in sample(range(6),6):print L[i-1],"buys for",L[i]

Python - 120 karakter

import random as R;L="Andy Barb Carl Didi Earl Fran".split();R.shuffle(L)
for i in range(6):print L[i-1],"buys for",L[i]

2

R - 85 karakter

paste(n<-sample(c('Andy','Barb','Carl','Didi','Earl','Fran')),'buys for',n[c(6,1:5)])

1

Python - 154 karakter

import random as R;L="Andy Barb Carl Didi Earl Fran".split();M=L[:]
while any(map(str.__eq__,L,M)):R.shuffle(M) 
for i in zip(L,M):print"%s buys for %s"%i

Özür dilerim, Python'umda ciddi bir eksiklik yok ... while döngüsü, "X için X satın alımlarından" kaçınan bir çözüm bulana kadar döngü yapıyor mu?
Steve

@Steve: Yaptığı şey bu. L ve M'deki her bir karşılık gelen değer çiftini mapçağırır str.__eq__ve döngü hiçbiri doğru olana kadar devam eder.
Anon.

@Steve, evet. jsut kayıtları 1'den 5'e kadar rastgele bir miktarda kaydırmak muhtemelen daha kısa olsa da, bu sorunun ruhunda olmadığını düşünüyorum
gnibbler

Soruyu işte ilk sorduğumda, haklısın. İş arkadaşlarım hızlı bir şekilde benim tanımlarım tarafından göz ardı edilmediğine dikkat çekti ... bu yüzden buraya yazarken olduğu gibi bıraktım.
Steve

1

D: 233 Karakter

import std.random,std.stdio;void main(){auto p=["Andy","Barb","Carl","Didi","Earl","Fran"];auto q=p.dup;o:while(1){for(int i;i<6;++i)if(p[i]==q[i]){randomShuffle(q);continue o;}break;}foreach(i,a;p)writefln("%s buys for %s",a,q[i]);}

Daha okunaklı:

import std.random, std.stdio;

void main()
{
    auto p = ["Andy", "Barb", "Carl", "Didi", "Earl", "Fran"];
    auto q = p.dup;

    o:while(1)
    {
        for(int i; i < 6; ++i)
            if(p[i] == q[i])
            {
                randomShuffle(q);
                continue o;
            }

        break;
    }

    foreach(i, a; p)
        writefln("%s buys for %s", a, q[i]);
}

1

Python (175)

import random as r
n=['Andy','Barb','Carl','Didi','Earl','Fran']
m=n[:]
r.shuffle(m)
b=' buys for '
for i in n:
 h=m.pop()
 while h==i:
  m.append(h)
  h=m.pop()
 print(i+b+h)

1

Şema, 173

İki çözümden birini verir.

(define(m lst)
    (printf"~v buys for ~v~n"(car lst)(cadr lst))
    (if(eq?(cadr lst)'Andy)0(m(cdr lst)))
)
(m((if(odd?(random 2))reverse values)'(Andy Barb Carl Didi Earl Fran Andy)))

1

C #, 210 183 karakter

using System;class a{static void Main(){var n="Andy Barb Carl Didi Earl Fran".Split();var c=0,i=new Random().Next(1,6);for(;c<6;c++)Console.WriteLine(n[c]+" buys for "+n[(c+i)%6]);}}

Boyler yığınları :(

Bu çözüm tamamen rastgele değildir - örneğin A-> C-> E-> A gibi bir veya daha fazla "döngü" vardır ve ofsetler döngülerde her zaman aynıdır. Ancak, bu çıktının bir parçası yoksa belirli bir çalışmanın çıktısını tahmin etmek mümkün değildir.


Bu benim niyet ettiğim yorum (ve temelde iniştiğimiz çözüm).
Steve

210 olmalıdır. Dosyanın sonundaki yeni satırı sayıyor musunuz?
gnibbler

@gnibbler: Muhtemelen öyleydim. Dosyayı wc'ye ekledim, bunu elle saymayacağım.
Anon.

1
Ne olmuş var n="Andy Barb Carl Didi Earl Fran".Split()? 16 bayt tasarruf sağlar. Main()9 baytlık tasarruf sağlayan argümanı dışarıda bırakabilirsiniz . Ve ilanını birleştirebilir cve i: int c,i=...;for(c=0;...başka bir iki kaydeder.
Joey

@Joey: Önerilerinize göre ayarladınız, teşekkürler.
Anon.

0

Ruby - 89 karakter

(a=%w(Andy Barb Carl Didi Earl Fran).shuffle).zip(a.reverse).each{|e|puts e*' buys for '}

Çıktı:

Andy buys for Didi
Barb buys for Earl
Fran buys for Carl
Carl buys for Fran
Earl buys for Barb
Didi buys for Andy

1
Bunun mapyerine kullanabilirsiniz each.
Dogbert

1
Bu çözüm ile sorun olduğunu insanların tek bir sayı orta kişi irade hediye varsa kendileri Earl Fran Mark alımlara yönelik Barb Andy alımlara yönelik Didi Carl alımlara yönelik Carl Didi alımlara yönelik Andy Barb alımlara yönelik Mark Fran alımlara yönelik Earl satın alır
StudleyJr

0

MathGolf , 41 bayt

"δ%è╘+µ√♂JÇ"2/$╦╕ää▐δáw_╪" buys for "+m+n

Çevrimiçi deneyin!

açıklama

Bunun, her durumu eşit olasılıkla üreteceği garanti edilmez, ancak her işlemde farklı sonuçlar üretir. Bir shuffle operatörünüz varsa bir bayt çıkarılabilir, ancak bu başka bir gün için.

"δ%è╘+µ√♂JÇ"                                push the string "δ%è╘+µ√♂JÇ"
            2/                              split into segments of two characters
              $                             transform to ordinals using base 256
               ╦                            fetch dictionary words (['Andy', 'barb', 'Carl', 'Earl', 'Fran'])
                ╕ää                         Push "didi"
                   ▐                        append to end of list
                    δ                       capitalize all strings in list
                     áw                     sort by random character in each string (shuffle)
                       _                    duplicate TOS
                        ╪                   right-rotate bits in int, list, str
                         " buys for "       push the string " buys for "
                                     +      Add to all strings in list
                                      m+    zip add the two arrays
                                        n   join array with newline
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.