รับตัวเลขสุ่ม n ตัวเลขด้วยตัวเลขที่แตกต่างกันและไม่ใช่ 0


22

ฉันอ่านคำถามนี้และคิดว่ามันจะเป็นการท้าทายที่ดี

งาน

ให้อินพุต0<n<10สร้างตัวเลขสุ่มด้วย

  • ตัวเลขที่แน่นอน
  • ครั้งแรกไม่ได้ 0
    • ดังนั้น f(n)>10**(n-1)-1
  • ตัวเลขที่แตกต่างกัน

เกณฑ์การชนะ

นี่คือเพื่อให้ได้รหัสที่สั้นที่สุด

สุ่ม

ฉันหมายถึงการกระจายแบบสุ่มอย่างสม่ำเสมอ ดังนั้นจากมุมมองของโปรแกรมแต่ละหมายเลขที่เป็นไปได้มีโอกาสเดียวกัน หากภาษาที่คุณกำลังเขียนมีตัวสร้างตัวเลขสุ่มแปลก ๆ ก็ไม่เป็นไรที่จะใช้มัน

ตัวอย่าง

รายการค่าที่จะเลือกแบบสุ่มสำหรับn=2คือ:

[10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98]
code-golf  number  random  grid  game  king-of-the-hill  javascript  code-golf  arithmetic  statistics  code-golf  math  code-golf  math  code-golf  string  palindrome  code-golf  string  interactive  code-golf  quine  polyglot  code-golf  string  stack-exchange-api  code-golf  number-theory  decision-problem  code-golf  tips  code-golf  string  internet  code-golf  graphical-output  image-processing  fractal  code-golf  ascii-art  geometry  hexagonal-grid  code-golf  string  restricted-source  hello-world  code-golf  game  code-golf  cipher  code-golf  permutations  cops-and-robbers  permutations  cops-and-robbers  code-golf  internet  stack-exchange-api  code-golf  ascii-art  random  code-golf  tips  code-golf  ascii-art  code-golf  code-golf  kolmogorov-complexity  code-golf  string  unicode  code-golf  number  sequence  primes  palindrome  code-golf  game  decision-problem  code-golf  math  geometry  code-golf  graphical-output  interactive  code-golf  set-partitions  code-golf  number  arithmetic  restricted-source  code-golf  decision-problem  python  recursion  code-golf  ascii-art  code-golf  source-layout  code-golf  function  recursion  functional-programming  code-golf  game  combinatorics  permutations  code-golf  string  file-system  code-golf  string  hashing  code-golf  stack-exchange-api  code-golf  string  code-golf  math  number  arithmetic  polyglot 


ส่งคืนเป็นจำนวนเต็มไม่ใช่สตริงใช่หรือไม่
Giuseppe

@Giuseppe สร้างหมายเลขสุ่ม
mbomb007

4
ฉันคิดถึงสิ่งนี้ทุกครั้งที่มีคนสร้างคำถามตัวเลขสุ่มxkcd.com/221
Thunda

1
@ ais523 "ให้อินพุต 0 <n <10 สร้างตัวเลขสุ่มด้วย"
cleblanc

คำตอบ:


17

Python 2 , 77 ไบต์

from random import*
r=range(10)
while[1]>r:shuffle(r)
print`r`[1:input()*3:3]

ลองออนไลน์!

สลับรายการ 10 หลักจนกว่าจะไม่ขึ้นต้นด้วย 0 จากนั้นสร้างตัวเลขที่มีรายการแรกเป็นnหลัก


แน่นอนทำงานได้เร็วขึ้นและมีหน่วยความจำน้อยลงสำหรับใส่ของหรือ9 10
mbomb007

วิธีแก้ปัญหาเรียบร้อย! คุณสามารถอธิบายวิธีการ[1::3]แปลงจากรายการเป็นสตริงได้อย่างไร ฉันไม่เคยเห็นแบบนั้นมาก่อน
Julian Wolf

@JulianWolf มันจะทำงานได้ก็ต่อเมื่อองค์ประกอบแต่ละรายการมีความยาวเท่ากัน มันจริงจะเป็นตัวแทนสตริงของรายการแล้วชิ้นมันพาตัวละครทุกตัวที่ 3 [หลังจากการกระโดดครั้งแรก
mbomb007

@JulianWolf [1::3]รับตัวละครที่ดัชนี 1 จากนั้นทุก ๆ สาม สำหรับ[1, 2, 3]ที่ให้123ข้ามวงเล็บเครื่องหมายจุลภาคและช่องว่าง
เดนนิส

ยิงโอเค - มันสมเหตุสมผลแล้ว ฉันลืม[1, 2, 3]ไปแล้วว่าได้รับการทำให้เป็นสตริงและจุลภาคและช่องว่างนั้นจำเป็นต้องข้าม ขอบคุณ!
Julian Wolf

10

Brachylogขนาด9 10 ไบต์

{~lℕ₁≜≠}ᶠṛ

ลองออนไลน์!

ตามปกติสำหรับ Brachylog นี่คือการส่งฟังก์ชั่น ลิงก์ TIO ด้านบนได้รับอาร์กิวเมนต์บรรทัดคำสั่งเพื่อทำให้ฟังก์ชันเป็นโปรแกรมแบบเต็ม

ผมต้องเพิ่มไบต์พิเศษจากรุ่นแรกนี้มีการเปลี่ยนแปลงเพื่อℕ₁ให้ไม่อนุญาตการส่งออก 0 (บางสิ่งบางอย่างที่ได้รับในขณะนี้ชี้แจง)

คำอธิบาย

{~lℕ₁≜≠}ᶠṛ
{      }ᶠṛ  Pick a random value with these properties:
 ~l           it has length equal to the input;
   ℕ₁         it's a positive integer;
     ≜        it's a specific value (not a constraint);
      ≠       all its elements (digits in this case) are different.

ไม่มีประสิทธิภาพพอสมควรเพราะล่ามสร้างรายการของค่าที่เป็นไปได้ทั้งหมดแล้วเลือกหนึ่งค่าแบบสุ่ม (นั่นคือสิ่งที่มีความᶠṛหมาย Brachylog ไม่มีตัวเลือก "เลือกวิธีการแก้ปัญหาแบบสุ่ม" ในเวลาที่ถามคำถามนี้)

ความคิดเห็นบางประการเกี่ยวกับการติดฉลากที่นี่: หากถูกละไว้ส่วนภายในวงเล็บปีกกาจะสร้างเพียงหนึ่งค่าข้อ จำกัด ที่ใช้แทนตัวเลขที่มีคุณสมบัติที่เราต้องการ การเลือกผลลัพธ์แบบสุ่มทำให้เรามีข้อ จำกัด และล่ามจะส่งออกค่าสัมบูรณ์ขั้นต่ำที่ตรงกับข้อ จำกัด (1, 10, 102, 1023, 10234, ฯลฯ ) ซึ่งไม่ใช่สิ่งที่เราต้องการ เราต้องบังคับให้สร้างรายการผ่านการติดฉลากที่ชัดเจน

การใช้งานภาษาโพรล็อกส่วนใหญ่ที่ฉันเคยเห็นมีบิวอินเพื่อค้นหาผลลัพธ์แบบสุ่มที่ตรงกับข้อ จำกัด แต่โดยทั่วไปแล้วจะไม่มีความน่าจะเป็นแบบเดียวกัน Brachylog ไม่มี แต่ (มีเพิ่มในการตอบสนองต่อความท้าทายนี้ แต่เห็นได้ชัดว่าฉันไม่สามารถใช้งานได้เนื่องจากกฎของช่องโหว่) ถ้าเป็นเช่นนั้นและถ้าเกิดขึ้นเพื่อให้ความน่าจะเป็นแบบเดียวกันกับปัญหานี้โปรแกรมนี้จะ~lℕ₁≠ตามมาด้วยตัวนั้นในระยะเวลา 6 ไบต์

Brachylogขนาด 8 ไบต์โดยร่วมมือกับ @Faleize

~lℕ₁≠≜ᶠṛ

ลองออนไลน์!

นี่เป็นกลอุบายระดับต่ำอัจฉริยะที่เหมาะสมกับวิธีที่ Prolog ทำสิ่งต่าง ๆ และไม่สมเหตุสมผลเมื่ออธิบายทางคณิตศาสตร์

ก่อนหน้านี้~lℕ₁≠สร้างค่าที่อธิบายข้อ จำกัด ("ความยาวเท่ากับอินพุตจำนวนธรรมชาติองค์ประกอบทั้งหมดแตกต่างกัน") จากนั้น≜ᶠสร้างค่าที่เป็นไปได้ทั้งหมดที่ตรงตามข้อ จำกัด จุดนี่เป็นที่ที่มีลำดับการประเมินผลของ Brachylog ไม่มีทางเลือกที่เกิดขึ้นจริงจะทำจนกว่าจะปรากฏขึ้นดังนั้น "พบว่าการแก้ปัญหาทั้งหมด" การดำเนินการจำเป็นต้องนำไปใช้กับอะไร แต่ "ค่าเฉพาะที่ตอบสนองข้อ จำกัด" การดำเนินการ นั่นหมายความว่าไม่จำเป็นต้อง{…}เลือกขอบเขตเพื่อประหยัด 2 ไบต์


ฉันจะโพสต์วิธีแก้ปัญหาด้วย≜₁ก่อนที่ฉันจะรู้ว่ามันถูกเพิ่มเข้ามาเนื่องจากความท้าทายนี้
Unrelated String

8

เยลลี่ขนาด 9 ไบต์

⁵*ṖQL$€MX

ลองออนไลน์! (จะไม่ทำงานที่ TIO สำหรับ n> 6เนื่องจากความไม่มีประสิทธิภาพของการใช้งาน)

หรือการดำเนินการทางเลือกในสิ่งเดียวกัน:

⁵*ṖQL$ÐṀX

อย่างไร?

นี่เป็นเรื่องลับๆล่อๆและไม่มีประสิทธิภาพมาก! เยลลี่ทำสิ่งที่มีประโยชน์โดยปริยายเมื่ออะตอมคาดหวังรายการ แต่ได้รับจำนวนเต็ม (นี่คือโดยการออกแบบ)
รหัสนี้ใช้การกระทำที่เป็นประโยชน์สองสามประการต่อไปนี้:

  • monadic atom , "pop" เมื่อถูกเรียกด้วยอินพุตจำนวนเต็มโดยปริยายทำให้ช่วงที่จะป๊อปดังนั้นอินพุตของnทำให้เป็นครั้งแรก[1, 2, ... , n]จากนั้นก็ปรากฏขึ้นให้ผล[1, 2 , ... , n-1]

  • monadic atom Q, "de-replicate" หรือ "unique" เมื่อถูกเรียกด้วยอินพุตจำนวนเต็มโดยปริยายทำให้รายการทศนิยมเป็น de-ซ้ำกันดังนั้นอินพุตของnโดยที่:
    n = d k-1 × 10 k-1 + d k-2 × 10 k-2 + ... + d 1 × 10 + d 0
    แรกทำให้
    [d k-1 , d k-2 , ... , d 1 , d 0 ]
    แล้วให้ค่าที่ไม่ซ้ำกันโดย ปรากฏตัวครั้งแรก
    ดังนั้นสำหรับตัวอย่างเช่นn = 5835518จะให้ผลผลิต[5, 8, 3, 1]

นอกจากนี้อะตอม monadic M"ดัชนีองค์ประกอบสูงสุด" จะส่งกลับดัชนีของรายการสูงสุดจากรายการซึ่งจะช่วยประหยัดสองไบต์ในทางเลือกที่ชัดเจนกว่าของการทดสอบเพื่อความเท่าเทียมกันกับข้อมูลที่ป้อนเข้าและค้นหาดัชนีความ⁵*ṖQL$€=⁸TXจริงหรือ⁵*ṖðQL⁼ð€TX

⁵*ṖQL$€MX - Main link: n                       e.g. 2
⁵         - literal 10
 *        - exponentiate: 10^n                      100
  Ṗ       - pop (make range 1 to 10^n, then pop)    [1  ,2  ,...,21   ,22 ,23   ,...,97   ,98   ,99]
     $€   - last two links as a monad for €ach:
   Q      -   unique (makes a decimal list first)   [[1],[2],...,[2,1],[2],[2,3],...,[9,7],[9,8],[9]]
    L     -   length                                [1  ,1  ,...,2    ,1  ,2    ,...,2    ,2    ,1  ]
       M  - indexes of maximal elements             [        ...,21       ,23,   ...,97   ,98       ]
          -                                         - i.e. all n-digit numbers with n-distinct digits.
        X - pick a random element from that list

ทั้งหมดค่อนข้างไม่มีประสิทธิภาพทั้งในเวลาและหน่วยความจำ: รายการแรกของ10 nจำนวนเต็มและหนึ่งถูกยกเลิกแล้วสำหรับแต่ละเหล่านี้รายการของnจำนวนเต็ม (ไม่ใช่วัตถุ 4 บิตแฟนซีหรือ enum) ทำ จากนั้นยกเลิกการทำซ้ำ การยกเลิกการทำซ้ำนี้มีการใช้งานตามรายการอย่างสมบูรณ์ (ไม่มีชุด, ชุดเรียงหรือพจนานุกรมที่เกี่ยวข้องภายใต้ประทุนแต่ละหลักจะถูกตรวจสอบว่ามีอยู่ในรายการที่ได้รับผลลัพธ์ในที่สุด)
ออฟไลน์n = 7ใช้ ~ 0.5GB และใช้เวลา ~ 25 วินาทีในขณะที่n = 8ใช้ ~ 4GB และใช้เวลา ~ 5 นาที - ฉันไม่ได้กังวลกับการใช้งานn = 9เพราะฉันมี RAM 16GB เท่านั้น (ฉันเดาว่าจะใช้เวลาประมาณ 45 นาที )

อีกทางเลือกหนึ่งคือการใช้ÐṀตัวกรองแบบรวดเร็วเพื่อกรองให้น้อยที่สุด (ซึ่งนี่เป็นการเพิ่มค่าใช้จ่ายเล็กน้อยในการจัดการสำหรับจำนวนไบต์เดียวกัน)


โอ้ว้าว. ฉันพยายามทำสิ่งนี้มาก แต่พลาดเคล็ดลับในการเก็บค่าเพื่อส่งกลับในดัชนีรายการ (ผ่านการขยายส่วนที่เหมาะสมออกจากรายการ) แทนที่จะพยายามเก็บแยกไว้ นี่เป็นกลอุบายที่มีประโยชน์ในเยลลี่ค่อนข้างบ่อยและฉันมักจะพลาด

7

เยลลี่ 11 ไบต์

9Xœ|⁵ḶẊ¤ḣ¹Ḍ

ลองออนไลน์!

มันทำงานอย่างไร

9Xœ|⁵ḶẊ¤ḣ¹Ḍ  Main link. Argument: n

9            Set the return value to 9.
 X           Pick; pseudo-randomly select an integer from [1, ..., 9].
       ¤     Combine the three preceding links into a niladic chain.
    ⁵          Yield 10.
     Ḷ         Unlength; yield [0, ..., 9].
      Ẋ        Shuffle; pseudo-randomly select a permutation of [0, ..., 9].
  œ|         Multiset OR; prepend the selected integer to the selected permutation
             and remove the second occurrence of the first element.
         ¹   Identity; yield n.
        ḣ    Head; keep the first n digits of the permutation.
          Ḍ  Undecimal; convert from base 10 to integer.

นั่นเป็นวิธีที่ฉลาดมากที่จะลบที่ซ้ำกัน ...
รั่วนูน

7

JavaScript (ES6), 72 71 70 69 ไบต์

f=(x,y="")=>x?!y.match(z=Math.random()*10|0)&&y|z?f(x-1,y+z):f(x,y):y

นี่คือฟังก์ชันเวียนที่ใช้เวลาในจำนวนของตัวเลขx พารามิเตอร์ที่สองyในขั้นต้นตั้งค่าเป็นสตริงว่างเปล่าติดตามจำนวนเมื่อเราสร้างตัวเลขเป็นหลัก

ครั้งแรกที่เราสร้างหลักสุ่มZMath.random()*10|0กับ ตอนนี้เราต้องการตรวจสอบว่าYไม่ได้มีZและYและZไม่ได้ทั้ง0

!y.match(z)เราสามารถคำนวณสภาพครั้งแรกกับ y.match(z)ส่งกลับอาร์เรย์ (จริงเสมอ) ถ้าyมีz , null (เท็จ) มิฉะนั้น; การ!แปลงนี้เป็นบูลีนและพลิกกลับ

y|zเงื่อนไขที่สองจะถูกตรวจสอบด้วย แม้ว่าปีเป็นสตริง JS |โดยปริยายแปลงเป็นจำนวนเต็มเมื่อใช้ นี่เป็นจำนวนเต็มบวกถ้าyมีตัวเลขอยู่แล้ว0 เป็นอย่างอื่น ผลลัพธ์สุทธิคือการy|zส่งคืน0 iff yว่างเปล่าและzคือ0หรือจำนวนเต็มบวก

หากเงื่อนไขทั้งสองนี้เป็นจริงเราจะใส่ตัวเลขต่อท้ายy , ลดค่าxและเริ่มต้นกระบวนการใหม่อีกครั้ง มิฉะนั้นเราจะกลับไปที่จุดเริ่มต้นและหวังว่าตัวเลขหลักถัดไปจะทำงาน เมื่อxถึง0เราจะคืนค่าสตริงว่างเพื่อสิ้นสุดการเรียกซ้ำ


รุ่นก่อนหน้า:

f=(x,y)=>x?~y>>(z=Math.random()*10|0)&1&&y|z?z+f(x-1,y|1<<z):f(x,y):""

นี่เป็นฟังก์ชั่นวนซ้ำที่ใช้ในจำนวนหลัก พารามิเตอร์ที่สองที่ไม่ได้กำหนดในตอนแรกคือyคือตารางการค้นหา 10 บิตที่บอกเราว่ามีตัวเลขใดบ้างที่เราเก็บไว้เป็นจำนวนเต็มอย่างสะดวก

ครั้งแรกที่เราสร้างหลักสุ่มZMath.random()*10|0กับ ตอนนี้เราต้องการตรวจสอบว่าZ 'TH บิตอย่างมีนัยสำคัญน้อยที่สุดของปีไม่ได้ตั้งค่าและYและZไม่ได้ทั้ง0

เราสามารถคำนวณเงื่อนไขแรกด้วย~y>>z&1; invert y , เลื่อนzบิตไปทางขวาและใช้บิตที่มีนัยสำคัญน้อยที่สุดเท่านั้น สิ่งนี้ให้1หากเรายังไม่ได้สร้างตัวเลขที่เป็นปัญหาหรือ0 เป็นอย่างอื่น

เงื่อนไขที่สองนั้นค่อนข้างยากที่จะเข้าใจy/zในตอนแรก(ฉันพยายามใช้ตอนแรกเพื่อสร้างNaNว่าพวกเขาทั้งคู่เป็น 0) แต่ในบางครั้งฉันก็รู้ว่าy|zจะทำเคล็ดลับได้ง่ายๆ ผลลัพธ์คือ0 iff ทั้งyและzคือ0 ; จำนวนเต็มบวกมิฉะนั้น

หากทั้งสองของเงื่อนไขเหล่านี้เป็นจริง ( ~y>>z&1&&y|z) จากนั้นเราสร้างส่วนที่เหลือของจำนวนและย่อหน้าที่Z จำนวนที่เหลือถูกสร้างขึ้นโดยการเรียกใช้ฟังก์ชันอีกครั้งด้วยx-1และy|1<<z( yแต่ด้วยบิตที่ index zตั้งค่าเป็น1 ) เมื่อxถึง0เราจะคืนค่าสตริงว่างเพื่อสิ้นสุดการเรียกซ้ำ


5

ClojureScript, 81 79 ไบต์

#(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))

นี่เป็นฟังก์ชั่นนิรนามดังนั้นคุณต้องใช้มันดังนี้:

(#(...) {arguments})

โดยที่คุณแทนที่{arguments}ด้วยอาร์กิวเมนต์ของคุณ

คุณสามารถลองรหัสได้ที่นี่ (ClojureScript REPL)

ขอบคุณที่@cliffrootโกนทิ้ง 2 ไบต์!


รหัสขยาย:

(defn random-digits [n]
  (let [num-vector
        (subvec
          (shuffle (range 10))
          0 n)]
    (if (= (num-vector 0) 0)
      (recur n)
      (int (apply str num-vector)))))

คำอธิบาย:

8ฉันจะไปผ่านสายหนึ่งโดยหนึ่งโดยใช้การป้อนข้อมูลตัวอย่างของ


(defn random-digits [n] ...)

สวยเรียบง่ายนี้กำหนดฟังก์ชั่นที่มีอาร์กิวเมนต์หนึ่งที่เรียกว่าrandom-digits nในคำตอบของฉันฉันใช้ฟังก์ชั่นที่ไม่ระบุชื่อ ( #(...)) เพื่อบันทึกไบต์


(let [num-vector ...] ...)

ลองดูข้างในletจากข้างในข้างนอก:

(shuffle (range 10))

ใน ClojureScript (และ Clojure) (range n)คล้ายกับ Python range(n): มันให้รายชื่อทุกหมายเลขจาก0ถึงn - 1( 9ในกรณีนี้)

shuffleรับรายการและส่งคืนเวกเตอร์ (ซึ่งแตกต่างจากรายการเล็กน้อย) โดยมีการสลับองค์ประกอบทั้งหมด ดังนั้นโดยใช้ตัวอย่างของเราเราได้รับสิ่งนี้:

[1 0 8 3 6 7 9 2 4 5]

(subvec {see above} 0 n)

(subvec vector start end)ยิงเวกเตอร์ (เฉพาะเวกเตอร์) และผลตอบแทนเวกเตอร์ซึ่งมีองค์ประกอบทั้งหมดจากดัชนีการstart endในกรณีนี้เรากำลังการองค์ประกอบจาก0องค์ประกอบ TH random-digitsอาร์กิวเมนต์ที่กำหนดให้ หากเรานำสิ่งนั้นไปใช้กับตัวอย่างเราจะได้รับ:

[1 0 8 3 6 7 9 2]

(if (= (num-vector 0) 0)
  (recur n)
  (int (apply str num-vector)))

นี้ifคำสั่งตรวจสอบว่าองค์ประกอบแรกของเป็นnum-vector0

ถ้าเป็น0แล้วเราเรียกใช้ฟังก์ชันอีกครั้งกับการโต้แย้งโดยใช้nrecur

ถ้าไม่ใช่0:


(int (apply str num-vector))

(apply function list)ใช้รายการและแยกออกเป็นฟังก์ชันเป็นอาร์กิวเมนต์ ตัวอย่างเช่น:

(apply + [2 3 4])

กลายเป็น:

(+ 2 3 4)

9ซึ่งเท่ากับ

(str items)เปลี่ยนทุกรายการitemsให้เป็นสตริงจากนั้นเชื่อมต่อรายการเหล่านั้นเข้าด้วยกัน intแปลงอะไรเป็นจำนวนเต็ม ดังนั้นถ้าเราใช้สิ่งนี้กับตัวอย่างเราจะได้:

   (int (apply str [1 0 8 3 6 7 9 2]))
=> (int (str 1 0 8 3 6 7 9 2))
=> (int "10836792")
=> 10836792

ซึ่งเป็นคำตอบสุดท้ายของเรา


2
ต้องรัก ClojureScript เพราะยอมให้(int string)แทน(Integer/parseInt string):)
หน้าผา

1
@cliffroot ฉันหมายความว่าคุณสามารถทำได้read-stringใน Clojure แต่มันไม่ดีกว่ามาก ...
353 clismique clismique

บันทึก 2 ไบต์#(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))ย้ายapply strส่วนหนึ่งไปยังจุดสิ้นสุด, อนุญาตให้เปรียบเทียบกับ0แทน\0และใช้subvecแทนtakeอนุญาตให้ใช้เวกเตอร์เป็นฟังก์ชันและเพื่อลบfirst
cliffroot

@cliffroot ฮะไม่ทราบว่าเปิดคอลเลกชันเป็นshuffle vecขอบคุณ! จะต้องเขียนคำอธิบายใหม่แม้ว่า ...
clismique

5

Python 2, 89 81 80 ไบต์

from random import*
lambda n:choice([i for i in range(10**n)if`set(`i`)`[5*n:]])

ลองออนไลน์


ฉันไม่คิดว่าคุณต้องการค่าเริ่มต้นสำหรับช่วง
เดนนิส

ดี! นั่นจะทำให้ช้าลง : D แย่มากฉันไม่สามารถใช้ตัวสร้างแทนรายการได้
mbomb007

เพียง 11% วางในที่ฝากข้อมูลสำหรับรหัสกอล์ฟ
เดนนิส

ใช่ฉันควรใช้99**nเพียงเพื่อให้แน่ใจว่าฉันได้รับพวกเขาทั้งหมด : D
mbomb007

ผมมองไปที่การทำอย่างนี้เหมือนกัน แต่มี 80 if`set(`i`)`[5*n:]]โดยใช้
Jonathan Allan

5

R, 45 ไบต์

k=0
i=scan()
while(!k[1])k=sample(0:9)[1:i]
k

ฉันคิดว่าคุณสามารถตั้งค่าได้k=0เนื่องจากมันเป็นเวกเตอร์โดยนัยของความยาวหนึ่งและคุณสามารถใช้ i = scan () เพื่อรับอินพุตจาก stdin เป็นตัวเลขได้ ฉันยังไม่แน่ใจว่ารายการของตัวเลขเป็นการส่ง "ถูกต้อง" แต่ฉันไม่ใช่ผู้ตัดสิน
Giuseppe

@Giuseppe ขอบคุณสำหรับข้อมูลอัปเดตข้อเสนอแนะของคุณทั้งสอง (ทั้งโพสต์) ขอบคุณ
Neil

จะwhile(!k[1])ทำงานเพื่อบันทึก 2 ไบต์หรือไม่
BLT

@BLT อัปเดตขอบคุณ
Neil

3

Bash + GNU utils, 46

seq 1e$[$1-1] 1e$1|egrep -v '(.).*\1'|shuf -n1

ลองมันออนไลน์

การดำเนินการนี้ใช้เวลานานสำหรับn ที่ใหญ่กว่า- ประมาณ 30 วินาทีสำหรับ n = 7 และเพิ่มขึ้น 10 เท่าสำหรับการเพิ่มขึ้นแต่ละครั้งดังนั้นอาจใช้เวลา 8-9 ชั่วโมงสำหรับ n = 10


ตามคำถาม n = 10 ไม่จำเป็นต้องทำงานแม้แต่น้อยต้องเร็วกว่ามาก
ysth

3

Java 7, 150 147 145 134 ไบต์

String c(int n){String r="";for(int l,x;(l=r.length())<n;)if(l<1&(x=(int)(Math.random()*10))>0|(l>0&!r.contains(""+x)))r+=x;return r;}

-2 ไบต์ต้องขอบคุณ@TheLethalCoder

(เก่า)คำอธิบาย:

String c(int n){                           // Method with integer parameter and String return-type
  String r="";                             //  Result-String
  for(int l=0,x;l<n;l=r.length()){         //  Loop until the length of the result-String is equal to the parameter integer
    x=new java.util.Random().nextInt(10);  //   Random digit
    if((l<1&x>0)                           //   If the length is zero and the random digit is not zero
       |(l>0&!r.contains(""+x)))           //     or the length is at least 1, and the result-String does not contain this random digit yet
      r+=x;                                //    Append the random digit to the result-String
  }                                        //  End of for-loop
  return r;                                //  Return result-String
}                                          // End of method

รหัสทดสอบ:

ลองที่นี่

class M{
  String c(int n){String r="";for(int l,x;(l=r.length())<n;)if(l<1&(x=(int)(Math.random()*10))>0|(l>0&!r.contains(""+x)))r+=x;return r;}

  public static void main(String[] a){
    M m = new M();
    System.out.println(m.c(4));
    System.out.println(m.c(10));
  }
}

ตัวอย่างผลลัพธ์:

7194
8672953041

คุณไม่สามารถใช้แลมบ์ดานิพจน์ที่นี่ได้ไหม? นั่นn->...คือ Java 8+ หรือเปล่า
TheLethalCoder

1
คุณสามารถยืมเคล็ดลับที่ฉันเพิ่งใช้ในคำตอบของฉันตั้งค่าความยาวในการตรวจสอบเปรียบเทียบfor(int l,x;(l=r.length())<n;)และคุณควรบันทึกไบต์
TheLethalCoder

1
@TheLethalCoder อ่าแน่นอนขอบคุณ การทำงานเป็นทีมที่ยอดเยี่ยม! ;) และใช่n->...คือ Java 8 โดยส่วนตัวแล้วฉันชอบ codegolf ใน Java 7 แม้ว่า 8 จะสั้นกว่าเสมอ
Kevin Cruijssen

2

Perl 6 , 44 ไบต์

{(->{+[~] (^10).pick($_)}...*>9 x$_-1).tail}

ลองมัน

ขยาย:

{  # bare block with implicit parameter 「$_」
  (

    ->{  # pointy block lambda with no parameters

      +                # turn the following into a numeric
      [~]              # concatenate the following

        (^10).pick($_) # grab $_ digits at random from 0..9
    }

    ...                # keep doing that until

    * > 9 x $_-1       # one of them is big enough

  ).tail # return the last one (only valid one)
}


2

MATL , 15 ไบต์

`4Y2GZr1)48=]8M

ลองที่MATL Online!

คำอธิบาย

`        % Do...while
  4Y2    %   Push predefined literal '0123456789'
  G      %   Push input n
  Zr     %   Random sample of n unique characters from that string
  1)     %   Pick the first
  48=    %   Is it 48? This is the loop condition
]        % End. If top of the stack evaluates to true: next iteration
8M       % Push the latest random sample. Implicitly display

2

เยลลี่ 12 ไบต์

9×!X+!Œ?’ḣƓḌ

ปัจจุบันหนึ่งไบต์อยู่ข้างหลังคำตอบของฉัน Jelly อื่น ๆ แต่ฉันชอบอันนี้จริงๆ

ลองออนไลน์!

มันทำงานอย่างไร

9×!X+!Œ?’ḣƓḌ  Main link. No arguments.

9             Set the argument and the return value to 9.
  !           Yield 9!
 ×            Compute 9 × 9!.
   X          Pick; pseudo-randomly select an integer j from [1, ..., 9 × 9!].
     !        Yield 9!
    +         Compute k := j + 9!.
              The result will belong to [9! + 1, 10!].
      Œ?      Get the permutation P of R := [1, ..., r], with minimal r, such that
              P is the lexicographically k-th permutation of R.
              Since k belongs to [9! + 1, 10!], r = 10 and this generates a per-
              mutation between [2,1,3,4,5,6,7,8,9,10] and [10,9,8,7,6,5,4,3,2,1].
        ’     Subtract 1 from all integers in P.
          Ɠ   Read an integer n from STDIN and yield it.
         ḣ    Head; keep the first n digits of the permutation.
           Ḍ  Undecimal; convert from base 10 to integer.

2

APL (Dyalog) , 27 19 17 ไบต์

ต้องใช้⎕IO←0ซึ่งเป็นค่าเริ่มต้นในหลาย ๆ ระบบ

10⊥⊢↑{?⍨10}⍣{×⊃⍺}

ลองออนไลน์!

สลับตัวเลขจนกว่าจะมีผลบังคับใช้:

10⊥ ถอดรหัสจากเลขฐาน 10 เป็นหมายเลขปกติ

 เดอะเอ็น

 องค์ประกอบแรกของ

{... }⍣{... } ซ้ำฟังก์ชั่น ...
?⍨10 สับเปลี่ยนจำนวนเต็มบวกสิบครั้งแรก
จนกระทั่ง ...
⊃⍺ หลักแรกของความพยายามที่ผ่านมา
× เป็นบวก


1

Python 2 , 100 93 92 90 ไบต์

ขอบคุณ @ mbomb007 สำหรับการกำจัด 2 ไบต์

from random import*
def f(n):k=randint(10**~-n,10**n-1);return(n==len(set(`k`)))*k or f(n)

พยายามหมายเลขตามต้องการจนกว่าจะพบว่ามีตัวเลขที่ไม่ซ้ำกัน ฉันจะเดิมพันมีวิธีที่สะอาดกว่ามากในการทำเช่นนี้ แต่ไม่มีใครสนใจ


return(n==len(set(`k`)))*k or f(n). ลองออนไลน์
mbomb007


1

Perl, 48 ไบต์

1until$_=1+int rand 10**$n-1,/.{$n}/&&!/(.).*\1/

คำอธิบาย:

สร้างจำนวนเต็มแบบสุ่มซ้ำ ๆ จาก 1 ถึง 10 ** $ n-1 ปฏิเสธพวกมันจนกว่าจะมีหนึ่งความยาวที่ถูกต้อง (อย่างน้อย 10 ** ($ n-1)) โดยไม่มีตัวเลขซ้ำ


1

แบตช์ 156 ไบต์

@set/af=9,r=x=0
@for /l %%i in (1,1,%1)do @call:c
@echo %r%
@exit/b
:c
@set/a"d=9-%random%%%f,e=x>>d&1
@if %e%==1 goto c
@set/a"r=r*10+d,f=10,x|=1<<d

xรักษา bitmask ของตัวเลขที่ใช้ fระบุจำนวนหลักที่มีอยู่ (นับถอยหลังจาก 9) ตัวเลขสุ่มจะถูกสร้างขึ้นจนกว่าจะพบตัวเลขที่ไม่ได้ใช้ n=10อาจรองรับ 165 ไบต์:

@set/af=9,r=x=0
@for /l %%i in (1,1,%1)do @call:c
@echo %r:~1%
@exit/b
:c
@set/a"d=9-%random%%%f,e=x>>d&1
@if %e%==1 goto c
@set r=%r%%d%
@set/a"f=10,x|=1<<d

( rมีศูนย์นำหน้าพิเศษเพราะมันเป็นนักกอล์ฟมากขึ้น) วิธีการก่อนหน้านี้ที่ 165 ไบต์ใส่รหัสตัวแรกเป็นพิเศษและเกิดขึ้นกับการทำงานด้วยn=10(รุ่นที่เป็นตัวเลขใช้เวลาจริง 166 ไบต์!):

@set/ar=%random%%%9+1,x=0
@for /l %%i in (2,1,%1)do @set/a"x|=1<<d"&call:c
@echo %r%
@exit/b
:c
@set/a"d=%random%%%10,e=x>>d&1
@if %e%==1 goto c
@set r=%r%%d%

วิธีดั้งเดิมสำหรับ 170 ไบต์ยังใช้งานได้กับn=10:

@set/ar=%random%%%9+1
@for /l %%i in (2,1,%1)do @call:c
@echo %r%
@exit/b
:c
@set/ad=%random%%%10
@call set s=%%r:%d%=%%
@if not "%s%"=="%r%" goto c
@set r=%r%%d%

ใช้การจัดการสตริงเพื่อตรวจจับตัวเลขที่ซ้ำกัน


1

Bash , 66 ไบต์

a=0;while [[ $a == 0* ]];do a=`shuf -i0-9 -n$1|xargs`;done;echo $a

ลองออนไลน์!

ตรงไปข้างหน้าใช้ usu shuf, xargs เพื่อรวมสายและลองต่อไปในขณะที่ชุดค่าผสมเริ่มต้นด้วย 0

ไม่สามารถเอาชนะ 46 อักขระจากคำตอบอื่นได้ แต่เร็ว!


1

Pyth, 15 28 ไบต์

=+YhO9VtQ#KOTI!hxYK=+YKB;jkY

ลองที่นี่


1
ยินดีต้อนรับสู่ PPCG และงานที่ยอดเยี่ยมโดยใช้ภาษาการเล่นกอล์ฟทันทีที่ค้างคาว :-) ฉันเห็น 2 ประเด็นเล็ก ๆ : 1) ดูเหมือนว่าตัวเลขที่สองอยู่เสมอ0ดังนั้นฉันคิดว่าคุณจะต้องการเปลี่ยน^TttQเป็น^TtQ-1 ไบต์ โบนัส!). 2) ตัวเลขทั้งหมดในผลลัพธ์ต้องไม่ซ้ำกันดังนั้นคุณจะต้องบังคับให้เกิดขึ้นอย่างใด
ETHproductions

@ETHproductions Arg !! ขอบคุณสำหรับการชี้ให้เห็นว่า ฉันแก้ไขมันแล้ว
มาเรีย

1

C #, 127 132 128 126 125 ไบต์

n=>{var s="";for(int l,r;(l=s.Length)<n;)if((l<1&(r=new System.Random().Next(10))>0)|(l>0&!s.Contains(r+"")))s+=r;return s;};

ลองออนไลน์!

ยืมความคิดจากคำตอบของ @ KevinCruijssenเพื่อเริ่มต้นการสุ่มrในifคำสั่งเพื่อบันทึก 2 ไบต์

ค่อนข้างแน่ใจว่านี่สามารถเล่นกอล์ฟต่อไปได้ แต่ฉันไม่มีเวลา


รุ่นเก่าโดยใช้whileลูป:

n=>{var s="";while(s.Length<n){int r=new System.Random().Next(10);if(s.Length<1&r>0)s+=r;else if(!s.Contains(r+""))s+=r;}return s;};

ฉันไม่คิดว่ามันถูกต้อง สมมติว่าจำนวนเต็มสุ่มแรกคือ0มันเป็นครั้งแรกจะพยายามif(s.Length<1&r>0)ที่เป็นเท็จ แต่แล้วก็จะทำif(!s.Contains(r+""))ที่เป็นจริงและยังคงผนวก"0"ที่จะsเป็นหลักแรก
Kevin Cruijssen

@KevinCruijssen แก้ไขและเล่นกอล์ฟต่อไป
TheLethalCoder

1
@KevinCruijssen อ่าผมเคยทำงานมันออกไปในตัวอย่างของคุณคุณไม่จบ.Next(10)... ;กับ ดังนั้นจึงไม่มีการปรับปรุงเพิ่มเติม แต่ความคิดที่ดี
TheLethalCoder

1
ฉันเพิ่งโพสต์ไว้ และโอ๊ะคุณขวาฉันพลาดที่กึ่งลำไส้ใหญ่ .. คุณยังสามารถกอล์ฟมันเช่นนี้แม้ว่า: n=>{var s="";for(int l=0,r;l<n;l=s.Length)if((l<1&(r=new System.Random().Next(10))>0)|(l>0&!s.Contains(r+"")))r+=x;return s;};:)
เควิน Cruijssen

1
@KevinCruijssen ฉันเพิ่งยืมความคิดจากคำตอบของคุณในขณะที่คุณเขียนความคิดเห็นนั้น! ขอขอบคุณการปรับปรุงที่ดี
TheLethalCoder

1

C (gcc) , 123 122 100 95 104 103 99 97 ไบต์

อันนี้สร้างหมายเลขสุ่มจริง

j;f(n){for(int i,k=n,s[10]={j=0};n;s[i+=i?0:k==n]=!s[i]?j+=i*pow(10,--n):1)i=rand()%10;return j;}

ลองออนไลน์!

C (gcc) , 87 85 ไบต์

นี่คือการพิมพ์สตริงของตัวเลข

f(n){for(int i,k=n,s[10]={0};n;s[i+=i?0:k==n]=!s[i]?--n,putchar(48+i):1)i=rand()%10;}

ลองออนไลน์!


1

PHP, 65 63 ไบต์

while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x;

รับอินพุตจาก STDIN; ทำงานด้วย-nRทำงานด้วย

สร้างตัวเลขสุ่มระหว่าง1และ10^Nรวม;
ทำซ้ำในขณะที่การนับของตัวละครที่แตกต่างกันคือ N<


1
while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x;-2 Bytes
JörgHülsermann

0

Mathematica 65 60 Bytes

0For[a=11,Max@DigitCount@a>1,a=RandomInteger[10^{#-1,#}]]+a&

นี่คือรุ่นที่เร็วกว่า แต่เพิ่ม 9 ไบต์:

FromDigits@Join[f=(s=RandomSample)[r=Range@9,1],s[r/.f[[1]]->0,#-1]]&

0

Java 9 JShell, 86 ไบต์

n->new Random().longs(0,10).limit(n-1).reduce(new Random().nextInt(9)+1,(a,b)->a*10+b)

ลองออนไลน์!

หมายเหตุ: ฉันไม่นับการนำเข้าเนื่องจากแพ็คเกจเหล่านั้นจะถูกนำเข้าเป็นค่าเริ่มต้นใน JShell แต่ไม่มีลิงก์ลองใช้ออนไลน์ที่ฉันรู้จักสำหรับ JShell ดังนั้นฉันจึงจัดเตรียมหนึ่งสำหรับ Java 9 ที่มีรหัสส่วนหัวและส่วนท้ายเพื่อ ทำให้มันทำงานในบริบทนั้น ใน JShell คุณสามารถทำได้:

jshell> Function<Integer,Long> f =
   ...> n->new Random().longs(0,10).limit(n-1).reduce(new Random().nextInt(9)+1,(a,b)->a*10+b)
f ==> $Lambda$27/633070006@5702b3b1

แล้ว:

jshell> f.apply(6)
$26 ==> 746202

มันทำงานอย่างไร:

เรากำหนดฟังก์ชั่นจากจำนวนเต็มถึงยาวและสร้างกระแสสุ่มแบบไม่มีที่สิ้นสุดในช่วง 0-9 จำกัด ไว้ที่ไอเท็ม n-1 แรกจากนั้นลดด้วยการสุ่ม int จาก 1-9 เป็นค่าเริ่มต้นและ ฟังก์ชั่นที่คูณมูลค่าด้วย 10 และเพิ่มค่าถัดไปจากสตรีม

ฉันใช้เวลานานดังนั้นสิ่งนี้น่าจะใช้ได้ประมาณ 18 หลัก (n = 18)


0

C, 96 93 ไบต์

f(n){char d[11],i=0,r;for(;i++^10;d[i-1]=d[r=rand()%i],d[r]=47+i);*d^48?d[n]=0,puts(d):f(n);}

ฟิชเชอร์ - เยตส์สลับการเริ่มต้นจนกว่าตัวเลขแรกจะไม่เป็นศูนย์

เป็นชุดสมมติว่าrand()%iเป็นชุด (เนื่องจากส่วนใหญ่ฉันRAND_MAX/iออกจากส่วนที่เหลือเล็ก ๆ มีอคติน้อยมากอคตินี้จะเล็กลงเมื่อ RAND_MAX โตขึ้น)

เห็นมันทำงานแบบออนไลน์

เห็นมันสร้างตัวเลขที่ถูกต้องสำหรับเมื่อ n เท่ากับ 2 ดังแสดงในคำถาม


0

ความจริง 191 ไบต์

g(a:NNI):Complex INT==(a<1 or a>9=>%i;r:List NNI:=[];b:=a;repeat(a=0=>break;d:=random()$INT rem 10;a=b and d=0=>0;~member?(d,r)=>(a:=a-1;r:=cons(d,r)));reduce(+,[r.i*10^(i-1)for i in 1..#r]))

Ungolf มันผลการทดสอบ

-- Return one number of 'a' different random digits if 0<a<10
f(a:NNI):Complex INT==
    a<1 or a>9=>%i
    r:List NNI:=[];b:=a
    repeat
       a=0=>break
       d:=random()$INT rem 10
       a=b and d=0  =>0
       ~member?(d,r)=>(a:=a-1;r:=cons(d,r))
    reduce(+,[r.i*10^(i-1)for i in 1..#r])

(4) -> [[i,g(i)] for i in 0..10]
   (4)
   [[0,%i], [1,9], [2,76], [3,135], [4,6810], [5,48675], [6,415768],
    [7,7461539], [8,98421537], [9,825046739], [10,%i]]
                                          Type: List List Complex Integer
(5) -> [[i,g(i)] for i in [3,3,3,3,3,3,3,3,3]]
   (5)
   [[3,653],[3,128],[3,254],[3,268],[3,914],[3,594],[3,276],[3,240],[3,398]]


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.