ย้อนกลับเรียงแทรก


19

วัตถุประสงค์

สร้างรายการที่มีสัญญาณรบกวนเดิมจากการเคลื่อนไหวที่มีการจัดเรียงการแทรกเพื่อจัดเรียง รายการต้นฉบับจะมีตัวเลขทั้งหมดตั้งแต่0ถึงN-1(รวม) โดยที่Nขนาดของอินพุต

อินพุต

รายการที่มีการเคลื่อนไหวที่จำเป็นเพื่อเรียงลำดับรายการ แต่ละค่าแสดงถึงจำนวนช่องที่แทนที่ด้วยหมายเลขเดิม (สัญญาณรบกวน) ที่จะอยู่ในตำแหน่งที่ถูกต้องโปรดทราบว่ากระบวนการนี้มาจากด้านซ้ายไปทางขวา
ค่าที่ตำแหน่ง (ดัชนี 0) iในรายการอินพุตจะอยู่ระหว่าง0และiรวม
คุณไม่จำเป็นต้องจัดการอินพุตที่ไม่ถูกต้องพฤติกรรมใด ๆ เป็นที่ยอมรับในกรณีนี้ (เกิดความผิดพลาดวนซ้ำไม่สิ้นสุด ฯลฯ )

เอาท์พุต

รายการที่มีสัญญาณรบกวน

ทีละขั้นตอนในการสร้างการเคลื่อนไหว

Scrambled List | Moves to sort
[4,0,2,1,3,5]  | [0, , , , , ] #4 stay in place
[4,0,2,1,3,5]  | [0,1, , , , ] #0 is moved 1 slot to the left
[0,4,2,1,3,5]  | [0,1,1, , , ] #2 is moved 1 slot
[0,2,4,1,3,5]  | [0,1,1,2, , ] #1 is moved 2 slot
[0,1,2,4,3,5]  | [0,1,1,2,1, ] #3 is moved 1 slot
[0,1,2,3,4,5]  | [0,1,1,2,1,0] #5 is in the right place already
[0,1,2,3,4,5]

ดังนั้นสำหรับการป้อนข้อมูลที่จำเป็นในโปรแกรมของคุณเพื่อการส่งออก[0,1,1,2,1,0] โปรดทราบว่าการเคลื่อนไหวไม่ได้อยู่ในตำแหน่งในรายการเรียงลำดับ (สุดท้าย) แต่ในส่วนที่เรียงลำดับแล้ว (ส่วนที่เป็นตัวหนา)[4,0,2,1,3,5]

กรณีทดสอบ

[0,0,0] -> [0,1,2]
[0,1,0,1] -> [1,0,3,2]
[0,0,0,0,0,5] -> [1,2,3,4,5,0]
[0,1,2,3] -> [3,2,1,0]
[0,1,1,1] -> [3,0,1,2]
[0,1,1,2,1,0] -> [4,0,2,1,3,5]

การชนะ

นี่คือดังนั้นคำตอบที่สั้นที่สุดชนะ

code-golf  array-manipulation  code-golf  code-golf  animation  code-golf  restricted-source  code-golf  java  code-golf  decision-problem  graph-theory  code-golf  conversion  electrical-engineering  code-golf  ascii-art  code-golf  string  substitution  code-golf  math  code-golf  string  set-theory  code-golf  code-golf  compile-time  code-golf  kolmogorov-complexity  binary  code-golf  sequence  cops-and-robbers  code-golf  subsequence  card-games  code-golf  sequence  primes  code-golf  code-golf  number  graphical-output  music  code-golf  ascii-art  code-golf  string  lambda-calculus  code-golf  string  code-generation  code-golf  unicode  code-golf  math  combinatorics  code-golf  balanced-string  code-golf  sequence  cops-and-robbers  code-golf  sequence  cops-and-robbers  code-challenge  fastest-code  chess  code-golf  math  graphical-output  code-golf  string  hello-world  animation  code-golf  number  arithmetic  code-golf  integer  code-golf  code-golf  combinatorics  code-golf  kolmogorov-complexity  graphical-output  code-golf  string  code-golf  code-golf  game  code-golf  math  combinatorics  code-golf  ascii-art  popularity-contest  random  code-golf  arithmetic  number-theory  integer  code-golf  tips  underload  code-golf  math  sequence  primes  code-golf  math  path-finding  code-golf  ascii-art  primes  code-golf  kolmogorov-complexity  alphabet 

1
โปรแกรมอาจใช้ความยาวของรายการเป็นอินพุตได้หรือไม่
mbomb007

@ mbomb007 ไม่
ร็อด

เราสามารถใช้ขั้นตอน (n-1) แทนได้หรือไม่ อันแรกไม่จำเป็นเพราะมันเป็นศูนย์เสมอ
GB

@GB แน่ใจว่าตราบใดที่ผลลัพธ์ถูกต้องคุณสามารถใช้อัลกอริทึมใดก็ได้
Rod

คำตอบ:


14

เยลลี่ 12 ไบต์

L!_UÆ¡$œ?J’U

ลองออนไลน์!

คำอธิบาย

โดยทั่วไปเราสามารถดูรายการทั้งสอง (อินพุตและเอาต์พุต) เป็นการเข้ารหัสจำนวนเต็ม อินพุตเข้ารหัสจำนวนเต็มในฐานแฟกทอเรียลและเอาท์พุทเข้ารหัสเป็นจำนวนเต็มเป็นการเปลี่ยนแปลง โชคดีที่ Jelly มี builtins ซึ่งอยู่ใกล้กับการเข้ารหัสทั้งสองนี้อยู่แล้วดังนั้นจึงเป็นเรื่องของการเขียนโค้ดขนาดเล็กเพื่อแปลงเป็นจำนวนเต็มจากนั้นกลับไปเข้ารหัสอีกตัว

L!_UÆ¡$œ?J’U
   U           Reverse {the input}
    Æ¡         and convert from base factorial to integer;
  _   $        subtract that from
L!             the factorial of the length of {the input};
       œ?      then take the nth permutation of
         J     [1,2,...,l], where l is the length of {the input},
          ’    subtract 1 from every elevent,
           U   and reverse it

ในกรณีของแฟกทอเรียลพื้นฐานเราสามารถสังเกตได้ว่าองค์ประกอบแรกของรายการต้องเป็น 0 ส่วนที่สองสามารถเป็น 0 หรือ 1 ส่วนที่สามต้องเป็น 0/1/2 และอื่น ๆ ดังนั้นเราต้องย้อนกลับอินพุตเพื่อให้องค์ประกอบเข้าสู่ลำดับการเขียนปกติสำหรับการแปลงฐาน

นอกจากนี้สำหรับคำสั่งสัมพัทธ์ของการแปลงแฟคทอเรียลและการแปลงการเปลี่ยนแปลงเพื่อให้ตรงกับการดำเนินการที่ใช้การเรียงลำดับการแทรกเราต้องทำการปรับเปลี่ยนสองครั้ง: การย้อนกลับลำดับของการเรียงสับเปลี่ยนและการเรียงลำดับของรายการเอาท์พุท การย้อนกลับรายการเอาท์พุทเป็นเรื่องง่ายเพียงพอโดยต้องการเพียงแค่Uในตอนท้ายของโปรแกรม เพื่อย้อนกลับลำดับของการเรียงสับเปลี่ยนเราลบจากแฟคทอเรียลของความยาวอินพุต (สิ่งนี้ทำงานได้เนื่องจากฐานแฟกทอเรียลสร้างตัวเลขในช่วง 0 ถึง (ความยาว! -1) ในขณะที่การเรียงสับเปลี่ยนนั้น สร้างการแยกตัวแบบหนึ่งต่อหนึ่งที่จะยกเลิกตัวเลือกแบบตัวต่อตัวที่ปกติคุณจะได้รับเมื่อลบดัชนีการเปลี่ยนแปลงจากแฟคทอเรียล)

Jelly , 9 ไบต์ร่วมกับ @JonathanAllan

UÆ¡Nœ?J’U

โปรแกรมรุ่นนี้คล้ายกันมาก แต่ใช้วิธีที่ต่างกันในการสลับลำดับการเรียงสับเปลี่ยน เพียงแค่ลบอินพุตด้วยNก็เพียงพอที่จะทำให้œ?ลำดับในสิ่งที่ตรงกันข้าม นอกเหนือจากนั้นมันทำงานเหมือนกับโปรแกรมก่อนหน้า

ลองออนไลน์!


4
O_O คาถานี้คืออะไร?
DLosc

โอ้ดี - ฉันรู้ว่าฉันÆ¡และœ?อะตอมจะทำงานนี้ (ฉันได้เริ่มต้นแล้วพยายามที่จะใช้พวกเขาสำหรับความท้าทายนี้ก่อนหน้านี้ - ผมจึงใกล้เพียงที่จำเป็นL!ในการมี)
Jonathan Allan

รหัสที่ยอดเยี่ยม!
Greg Martin

1
ในความเป็นจริงคุณสามารถทำได้ใน9ไบต์ด้วยUÆ¡Nœ?L’Uเพราะฉันดำเนินการœ?(และคล้ายกัน) เพื่อทำหน้าที่โมดูลาร์ (ราวกับว่าพวกเขากำลังใช้รายการวุ้น) Nเพียงดัชนีด้วยค่าลบ หมายเหตุ: ฉันเปลี่ยนJเป็นL- นี่เป็นเพียงเพราะให้ตัวเลขมันทำให้ช่วงที่อยู่ภายใต้ประทุน)
Jonathan Allan

6

Mathematica, 92 ไบต์

Permute[Range[l=Length@#]-1,(c=Cycles@{#}&)@{}©##&@@c[i-0~Range~#[[i]]]~Table~{i,l,1,-1}]&

ฟังก์ชั่นที่บริสุทธิ์รับรายการของจำนวนเต็ม nonnegative เป็นข้อมูลเข้าและส่งกลับรายการของจำนวนเต็มไม่ใช่ลบ รหัสข้างต้นประกอบด้วย a ©, ซึ่งไม่ถูกต้อง: มันเป็นตัวยึดสำหรับสัญลักษณ์ 3 ไบต์ U + F3DE ซึ่ง Mathematica จะแทนด้วยวงกลมที่มีจุดอยู่ในนั้นและซึ่งแทนองค์ประกอบของการเรียงสับเปลี่ยน

c=Cycles@{#}&กำหนดฟังก์ชั่นที่แปลงรายการจำนวนเต็มเป็นCyclesวัตถุที่แสดงถึงการเปลี่ยนแปลง ตัวอย่างเช่นc[{3,4}]องค์ประกอบการสลับการแปลง 3 และ 4 ของรายการ c[i-0~Range~#[[i]]]~Table~{i,l,1,-1}]ใช้รายการอินพุตและสร้างการเรียงสับเปลี่ยนที่จำเป็นเพื่อเลิกทำการเรียงลำดับการแทรก จากนั้นรวบรวมทั้งหมดของพีชคณิตเหล่านี้ร่วมกันเริ่มต้นด้วยการเปลี่ยนแปลงตัวตนc@{}©##&@@ c@{}สุดท้ายPermute[Range[l=Length@#]-1,...]ใช้การเปลี่ยนแปลงนี้กับรายการ 0 ดัชนีที่มีความยาวที่เหมาะสม


1
ไม่มีอะไรในตัว! แน่นอน ...
Jonathan Allan

3
@{#}&)@{}©##&@@ดูน่ากลัว
Yytsi

6

Python 2, 79 68 ไบต์

ขอบคุณ Krazor สำหรับการบันทึก 10 ไบต์

ขอบคุณ TuukkaX ที่ช่วยประหยัด 1 ไบต์

a=input();b=range(len(a));print[b.pop(j-a[j])for j in b[::-1]][::-1]

ทำงานโดยการสร้างการเคลื่อนไหวในสิ่งที่ตรงกันข้าม


2
ทำที่66 ! วิธีการเกี่ยวกับ: a=input();b=range(len(a));print[b.pop(j-a[j]) for j in b[::-1]][::-1]. รายการความเข้าใจ ftw!
FMaz

1
@ Krazor คุณมีพื้นที่ที่สามารถลบออกได้ก่อนforดังนั้นให้65 ที่ฉันเดา: D
Yytsi

@ Krazor ปรากฎว่ารายการเข้าใจไม่ได้ผล แต่ฉันชอบความคิดในการใช้ b [:: - 1]!
คณิตศาสตร์ขี้ยา

ไม่มีทาง? ฉันแสดงความคิดเห็นกับมือถือบางทีฉันพิมพ์ผิดบางอย่าง ส่วนไหนไม่ทำงาน สำหรับฉันมันตีความอย่างถูกต้องและตอบสนองทุกกรณีทดสอบ
FMaz

@ Krazor โอ้โหคุณไม่มีสิทธิ์ ฉันเป็นคนหนึ่งที่พิมพ์ผิดในขณะทดสอบ
คณิตศาสตร์ขี้ยา

5

JavaScript (ES6), 69 65 63 ไบต์

a=>a.reverse(b=[...a.keys()]).map(o=>+b.splice(~o,1)).reverse()

น่ารำคาญทั้งอินพุตและเอาต์พุตอยู่ในลำดับที่ไม่ถูกต้อง แก้ไข: บันทึกแล้ว 4 ไบต์ขอบคุณ @Arnauld บันทึก 2 ไบต์ด้วย @ETHproductions


ฉันยังคงพยายามหาวิธีที่ดีกว่า แต่คุณก็เร็วกว่ามาก ทำได้ดีนี่!
Arnauld

1
คุณไม่ต้องการiคุณใช่ไหม
Arnauld

@Arnauld เห็นได้ชัดว่าไม่ ฉันเริ่มด้วยการพยายามเข้าใจคำตอบของ Python และฉันเพิ่งสังเกตเห็นว่ามันไม่ได้ใช้จริง ๆi...
Neil

1
ง่าย -2:o=>+b.splice(~o,1)
ETHproductions

3

JavaScript (ES6), 73 71 ไบต์

บันทึก 2 ไบต์ด้วย ETHproductions

m=>(a=m.map((_,i)=>j=i)).map(_=>a.splice(j,0,+a.splice(j-m[j--],1)))&&a

กรณีทดสอบ


วิธีที่ดีในการรับความยาวและช่วงในเวลาเดียวกัน ฉันจะแนะนำa=m.map(_=>j++,j=0)แต่นั่นคือความยาวเท่ากันและฉันแน่ใจว่าคุณได้ลองไปแล้ว
ETHproductions

@ETHproductions คุณพูดถูก: ฉันเคยลองแล้วเหมือนกัน :-) (มันอาจจะเป็นที่น่าสังเกตว่านี้จะไม่เทียบเท่า: นี้จะตั้งjไปa.lengthมากกว่าa.length-1และจะต้องมีa.splice(--j,0,a.splice(j-m[j],1)[0]))
Arnauld

เฮ้ฉันก็คิดแบบนั้นเหมือนกัน แต่ฉันก็ไม่คิดว่ามันคุ้มค่าที่จะพูดถึงเพราะมันมีความยาวเท่ากัน
ETHproductions

1
ง่าย -2:+a.splice(j-m[j--],1)
ETHproductions

2

Haskell , 85 ไบต์

f x|n<-length x-1=reverse x#[n,n-1..0]
(n:r)#l=r#(take n l++drop(n+1)l)++[l!!n]
x#l=x

ลองออนไลน์! ตัวอย่างการใช้งาน: อัตราผลตอบแทนf [0,1,1,2,1,0][4,0,2,1,3,5]

f xเรียกฟังก์ชั่น#ที่มีรายชื่อกลับรายการและรายการx ดำเนินการเรียงลำดับการแทรกย้อนกลับโดยการเอาองค์ประกอบที่ซ้ำออกมาโดยที่ให้ผลตอบแทนที่องค์ประกอบที่สามและผลผลิตรายการที่มีองค์ประกอบที่ลบออก[length x - 1, length x - 2, ... , 0](n:r)#lnll!!nntake n l++drop(n+1)lln


Haskell สวยงามมาก
FMaz

1

Perl 61 ไบต์

@o=@p=0..@ARGV-1;splice@o,$_,0,splice@o,$_-pop,1for reverse@p

เอาต์พุตสิ้นสุดในอาร์เรย์ @o ตัวอย่างที่มีอาร์เรย์อินพุตเป็นอาร์กิวเมนต์บรรทัดคำสั่ง:

perl -le'@o=@p=0..@ARGV-1;splice@o,$_,0,splice@o,$_-pop,1for reverse@p;print@o' 0 1 1 2 1 0
402135

1

Ruby, 49 ไบต์

->l{(w=l.size).times{l.insert(l.shift+w-=1,w)};l}

ดำเนินการ "การแทรกย้อนกลับ" ในสถานที่ภายในรายการเริ่มต้นด้วยจำนวนที่มากที่สุด

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