เรียงลำดับการตัดแบ่ง


17

พิจารณาลำดับที่อยู่บนพื้นฐานของความสัมพันธ์ที่เกิดขึ้นอีก, เริ่มต้นด้วยf(n) = f(n-1)+f(n-2) f(1) = x1, f(2) = x2สำหรับx1 = 2, x2 = 1ลำดับเริ่มต้นดังนี้:

2  1  3  4  7  11  18  29  47  76  123  199  322  521  843

การต่อสิ่งนี้เข้ากับสตริงจะทำให้:

213471118294776123199322521843

y(n) > y(n-1)ตอนนี้แบ่งรายการนี้ลงในตัวเลขที่เป็นไปได้น้อยที่สุดที่จะช่วยให้ เริ่มต้นด้วยหมายเลขแรกจากนั้นตัวเลขที่สองเป็นต้นหมายเลขผลลัพธ์แรกควรเป็นตัวเลขหลักเดียวเสมอ ปัดตัวเลขสุดท้ายด้วยเลขศูนย์ที่ต้องการ

2 13 47 111 829 4776 12319 93225 218430

คุณจะได้ตัวเลขสองตัว(x1, x2)เป็นอินพุตในรูปแบบที่สะดวกและความท้าทายคือการส่งออกรายการที่เรียงลำดับ

กฎ:

  • ฟังก์ชั่นและโปรแกรมก็โอเค
  • ลำดับเริ่มต้นจะต้องมี 15 หมายเลข (หมายเลขสุดท้ายf(15))
  • x1และx2ไม่เป็นลบ (ศูนย์เป็นไปได้)
  • เอาต์พุตสามารถอยู่ในรูปแบบที่สะดวก
  • เวกเตอร์การส่งออกจะต้องสร้างขึ้นเพื่อให้ yy2 > y1
    • ครั้งแรกที่เล็กที่สุดที่เป็นไปได้y1แล้วที่เล็กที่สุดที่เป็นไปได้y2แล้วy3และอื่น ๆ
  • ถ้าx1 = x2 = 0เอาท์พุท 15 ศูนย์ (ในรูปแบบเดียวกับเอาท์พุทอื่น ๆ เช่นไม่000000000000000)

ตัวอย่าง :

Input: 1 1
Output: 1  12  35  81  321  345  589  1442  3337 7610

Input: 3 2
Output: 3  25  71  219  315  0811 3121  23435 55898 145300
                             |
                             Optional leading zero 
Input: 0 0
Output: 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ โปรดใส่ลิงค์ไปยังล่ามออนไลน์หากเป็นไปได้


คุณหมายถึงอะไรโดย "ตัวเลขที่เล็กที่สุดที่เป็นไปได้"? ค่าเฉลี่ยน้อยที่สุด? เล็กที่สุด? อื่น ๆ อีก?
isaacg

@isaacg ดังนั้น nth number จึงมากกว่า (n-1) th
nicael

1
เพื่อชี้แจงคำถามของฉันการแบ่งที่เหมาะสม5467จะเป็นอย่างไร 54 67? 5 46 70?
isaacg


3
สิ่ง 0 ดูเหมือนว่าเป็นข้อยกเว้นที่น่ารำคาญและไม่จำเป็น
Martin Ender

คำตอบ:


1

Pyth, 56 ไบต์

LsgM.:sMb2?sQsM.WyHX_1Z`0u?yGX_1GHaGHjkhM.u,eNsN14QYmZ15

ชุดทดสอบ

คำอธิบาย:

ก่อนอื่นเราตรวจสอบว่าอินพุตถูกต้อง0, 0หรือไม่ หากเป็นเช่นนั้นให้พิมพ์ 15 ศูนย์

jkhM.u,eNsN14Qมิฉะนั้นเราผลิตลำดับด้วย สิ่งนี้คล้ายกับอัลกอริธึม Pyth มาตรฐานสำหรับลำดับฟีโบนักชี

ต่อไปเราจะลดข้อความนี้ แอคคูมูเลเตอร์คือรายการของสตริงที่แทนแต่ละหมายเลขในลำดับที่แบ่งออก ในการลดแต่ละขั้นตอนเราใช้ตัวละครถัดไปและตรวจสอบว่าตัวสะสมอยู่ในลำดับหรือไม่โดยใช้ฟังก์ชั่นตัวช่วยyซึ่งกำหนดด้วยLsgM.:sMb2ซึ่งเป็นความจริงถ้าอินพุตไม่เป็นระเบียบ หากเป็นไปตามลำดับเราจะผนวกอักขระถัดไปในรายการเป็นหมายเลขของมัน ถ้าไม่เราจะเพิ่มตัวละครต่อไปที่ส่วนท้ายของสตริงสุดท้าย u?yGX_1GHaGH ... Yนี่คือความสำเร็จกับ

ต่อไปเราดำเนินการในขณะที่วนรอบ การวนซ้ำจะดำเนินต่อไปจนกระทั่งรายการที่กำลังรันอยู่นั้นอยู่ในลำดับ ในแต่ละขั้นตอน0จะมีการเพิ่มa ต่อท้ายสตริงสุดท้ายในรายการ .WyHX_1Z`0นี่คือความสำเร็จกับ

ในที่สุดสตริงจะถูกแปลงเป็นจำนวนเต็มด้วยsMและพิมพ์


Pyth, 51 ไบต์

LsgM.:sMb2?sQsM.WyHX_1Z`0hf!yT_./jkhM.u,eNsN14QmZ15

ฉันเชื่อว่ามันใช้งานได้ แต่มันช้าเกินไปที่จะทดสอบ - มันเป็นคำตอบที่ดุร้ายสำหรับการแบ่งสตริง


ฉันจะทำการปรับปรุงXฟังก์ชั่นบางอย่างแต่โค้ดด้านบนใช้งานได้ในเวอร์ชันของ Pyth ที่ล่าสุดเมื่อคำถามถูกโพสต์


5

JavaScript ES6, 127 135

(a,b)=>eval("for(n=r=[],v=13,o=a+n+b;v--;a=b,b=t)o+=t=b+a;for(d of o+'0'.repeat(99))(n+=d)>+v&&(r.push(v=n),n='');+v?r:[...o]")

ทดสอบ

F=(a,b)=>eval("for(n=r=[],v=13,o=a+n+b;v--;a=b,b=t)o+=t=b+a;for(d of o+'0'.repeat(99))(n+=d)>+v&&(r.push(v=n),n='');+v?r:[...o]")

// less golfed

U=(a,b)=>{
  for(n=r=[], o=a+n+b, v=13; v--; a=b, b=t)
    o+= t= b+a;
  for(d of o+'0'.repeat(99))
    if ((n+=d) > +v)
      r.push(v=n), n='';
  return +v ? r : [...o]
}

function test(){
  var i = I.value.match(/\d+/g)
  O.textContent = i.length > 1 ? F(+i[0],+i[1]) : ''
}
test()
A,B : <input id=I value='0 1' oninput='test()'>
<pre id=O></pre>


มีข้อผิดพลาดสำหรับ x1 = 0, x2> 0 เช่นอินพุต "0 1"
flornquake

@ flornquake แก้ไขแล้ว จำนวนไบต์ยังคงเหมือนเดิมโดยลดรหัสการเติมให้เป็นศูนย์เล็กน้อย
edc65

2

JavaScript ES6, 187 180 187 184 182 179 175 172 165 160 155 154 ไบต์

(a,b)=>eval('d=""+a+b;for(i=-12,j=1;++i<99;)i<2?(c=b,d+=b=a+b,a=c,r=a?[d[0]]:"0,".repeat(15)):(f=+d.slice(j,i))>r[r.length-1]?(r.push(f),j=++i-1):d+=0;r')

ฉันได้รับผลลัพธ์ที่คล้ายกันเมื่อรัน1,1และ3,2ทดสอบเคส 0,0ได้ใช้งานเกิน 26 ไบต์ ...

De-golf + แปลงเป็น ES5 + ตัวอย่าง:

function s(a, b) {
  d = "" + a + b;
  for (i = -12, j = 1; ++i < 99;)
    i < 2 ?
      (c = b, d += b = a + b, a = c, r = a ? [d[0]] : "0,".repeat(15))
    : (f = +d.slice(j, i)) > r[r.length - 1] ?
      (r.push(f), j = ++i - 1)
      : d += 0;
  return r
}
document.write(
   s(1,1)+"<br>"+
   s(3,2)+"<br>"+
   s(0,0)
)


เพราะเหตุใดจึงสร้างตัวเลขมากขึ้น และไม่ควรแก้ไขได้ง่าย? n <= 15ความต้องการคือ
Stewie Griffin

@Stewie แต่เฮ้คนแรกสร้าง 12 และ 11 คนที่เล็กกว่า 15
nicael

ลำดับเริ่มต้นf(n) = f(n-1)+f(n-2)มีค่าสูงสุดที่แน่นอนจำนวน 15 ค่าของเอาต์พุตจะถูกกำหนดตามอัลกอริทึมไม่มีอะไรอื่น
Stewie Griffin

@Stewie ตกลงดังนั้นมันต้องเท่ากับ 15 จริงไหม? จากนั้นโดย n <= 15 คุณหมายถึงว่าหมายเลขอินพุตมีค่าน้อยกว่า 15?
nicael

จำนวนของค่าในลำดับเริ่มต้นคือ 15 ค่าเริ่มต้นf(1)=x1และf(2)=x2สามารถสูงกว่า 15 จำนวนของค่าเอาท์พุทจะถูกกำหนดขึ้นอยู่กับค่าอินพุต สำหรับ3 2มันจะเป็น 10
Stewie Griffin

1

JavaScript (ES6), 162 ไบต์

(a,b)=>(k=[...Array(15).keys(y="")],p=-1,z=k.map(_=>0),a|b?[...k.map(f=n=>n--?n?f(n)+f(n-1):b:a).join``,...z].map(d=>+(y+=d)>p?(p=y,y=" ",p):"").join``:z.join` `)

คำอธิบาย

(a,b)=>(
  k=[...Array(15).keys(y="")],     // k = array of numbers 0 to 14, initialise y
  p=-1,                            // initialise p to -1 so that 0 is greater than p
  z=k.map(_=>0),                   // z = array of 15 zeroes
  a|b?[                            // if a and b are not 0
      ...k.map                     // for range 0 to 14
      (f=n=>n--?n?f(n)+f(n-1):b:a) // recursive sequence function (0 indexed)
      .join``,                     // join result of f(0) to f(14) as a string
      ...z                         // append zeroes for padding
    ].map(d=>                      // for each digit of concatenated result
      +(y+=d)                      // append the digit to the current number y
      >p?(                         // if the current number is greater than the previous p
        p=y,                       // set previous to the current number
        y=" ",                     // reset y (with space as a separator)
        p                          // output the current number (with space at the start)
      ):""                         // else add nothing to the output
    )
    .join``                        // return the output as a string
  :z.join` `                       // return a bunch of zeroes if a and b are 0
)

ทดสอบ


1

Mathematica ขนาด 192 ไบต์

f[{0,0}]:=0~Table~15
f@l_:=(t=0;q={};If[#>0,q~Join~{10^⌈Log10[t/#]⌉#},q]&[Last@#]&@FoldList[If[#>t,AppendTo[q,t=#];0,#]&[10#+#2]&,0,Flatten@IntegerDigits@SequenceFoldList[#+#2&,l,Range@13]])

กรณีทดสอบ:

f[{2, 1}]
(* {2, 13, 47, 111, 829, 4776, 12319, 93225, 218430} *)
f[{3, 2}]
(* {3, 25, 71, 219, 315, 811, 3121, 23435, 55898, 145300} *)
f[{0, 0}]
(* {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} *)

ความยาวของชื่อฟังก์ชั่นกำลังฆ่าฉัน


1

Haskell, 165 159 152 142 141 ไบต์

w=take 15
x#y=x:scanl(+)y(x#y)
0%0=w[0,0..]
x%y=g(-1)(w(x#y)++0%0>>=show)(-1)
g _""_=[]
g b l@(h:t)a|b>a=b:g 0l b|1<2=g(max 0b*10+read[h])t a

ตัวอย่างการใช้งาน: ->3 % 2[3,25,71,219,315,811,3121,23435,55898,145300]

การสาธิตออนไลน์ (พร้อมmainเสื้อคลุม)

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

w=take 15
x#y=x:scanl(+)y(x#y)              -- fibonacci sequence generator for x and y

0%0=w[0,0..]                      -- special case 0%0
x%y=g(-1)(w(x#y)++0%0>>=show)(-1) -- calculate fib sequence, add some extra 0 and
                                  -- flatten all digits into a single string.
                                  -- start calculating the resulting sequence

g _""_=[]                         -- if we don't have digits left, stop.
                                  -- the final 0 in the second parameter is ignored.
g b l@(h:t)a
  |b>a=b:g 0l b                   -- if the current number is greater than the
                                  -- previous one, take it and start over.
  |1<2=g(max 0b*10+read[h])t a    -- otherwise add the next digit and retry.
                                  -- The "max" fixes the initial call with -1.

0

PowerShell, 167 166 ไบต์

param($x,$w)if($w-lt($x-eq0)){"0`n"*15;exit}[char[]]("$x"+-join(0..13|%{$w;$w=$x+($x=$w)}))|%{$z+="$_";if(+$z-gt$y){($y=$z);$z=""}};if($z){while(+$z-lt$y){$z+="0"}$z}

บันทึกไบต์โดยการกำจัด$sตัวแปรและเพียงแค่ป้อนลูปเอาท์พุทโดยตรง

Ungolfed และแสดงความคิดเห็น:

param($x,$w)           # Take input parameters as x and w
if($w-lt($x-eq0)){     # If x=0, ($x-eq0)=1, so $w-lt1 implies w=0 as well
  "0`n"*15             # Print out 15 0's separated by newlines
  exit                 # And exit program
}                      # otherwise ...
[char[]](              # Construct the sequence string as a char-array
"$x"+-join(            # Starting with x and concatenated with a joined array
  0..13|%{             # Loop
    $w                 # Add on w
    $w=$x+($x=$w)      # Recalculate for next loop iteration
  }
))|%{                  # Feed our sequence as a char-array into a loop
  $z+="$_"             # z is our output number, starts with the first digit
  if(+$z-gt$y){        # If z is bigger than y (initialized to 0)
    ($y=$z)            # Set y equal to z and print it
    $z=""              # Reset z to nothing to start building the next number
  }
}
if($z){                # If there is remaining digits, we need to pad zeroes
  while(+$z-lt$y){     # Until z is bigger than y
    $z+="0"            # Tack on a zero
  }
  $z                   # Print the final number
}

0

Perl 6 , 107 ไบต์

{$_=@=(|@_,*+*...*)[^15].join.comb;.sum??[.shift,{last if !@$_;until (my$a~=.shift//0)>$^b {};$a}...*]!!$_} # 107

การใช้งาน:

# give it a lexical name for ease of use
my &code = {...}

# use 「eager」 because the anonymous block returns a lazy array
# and 「say」 doesn't ask it to generate the values
say eager code 2, 1;
# [2 13 47 111 829 4776 12319 93225 218430]
say eager code 1, 1;
# [1 12 35 81 321 345 589 1442 3337 7610]
say eager code 3, 2;
# [3 25 71 219 315 0811 3121 23435 55898 145300]
say eager code 0, 0;
# [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
say eager code 0, 1;
# [0 1 12 35 81 321 345 589 1442 3337 7000]

คำอธิบาย

สร้างลำดับฟีโบนักชีเช่นเริ่มต้นด้วยอาร์กิวเมนต์ ( @_) slipped ( |) ใน

|@_,*+*...*

ใช้ 15 องค์ประกอบแรกของลำดับนั้น

(…)[^15]

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

$_=@=(…)[^15].join.comb;

มันจะหาผลรวมของค่าในสเกลาร์เริ่มต้นและหากเป็นศูนย์จะส่งคืนสเกลาร์เริ่มต้นซึ่งจะมีอาร์เรย์ 15 ศูนย์

.sum??  !!$_

ถ้าผลรวมไม่เป็นศูนย์มันจะสร้างรายการโดยเลื่อนองค์ประกอบแรกในสเกลาเริ่มต้นก่อน

.shift,  

ตามด้วยการสร้างค่าที่เหลือตรวจสอบเทียบกับค่าก่อนหน้า ( $^b)
หากสเกลาร์เริ่มต้นหมดค่าให้ใช้ 0 แทน ( //0)

…,{  ;until (my$a~=.shift//0)>$^b {};$a}...*

หยุดเมื่อไม่มีองค์ประกอบในเกลาเริ่มต้น

…,{last if !@$_;  }...*

ทำไมต้องมีที่ว่างในuntil (my$a...? คือ(ไม่ได้เป็นตัวคั่นพิเศษหรือไม่?
แมว

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