คำต่อท้ายของฉันประเภทใด


10

Intro

ดังนั้นฉันจึงเสียเวลาไปกับการค้นคว้าขั้นตอนวิธีการเรียงลำดับคำต่อท้ายประเมินความคิดใหม่ด้วยมือและในโค้ด แต่ฉันมักจะพยายามจำประเภทของคำต่อท้ายของฉัน! คุณบอกฉันได้ไหมว่าคำต่อท้ายของฉันคืออะไร?

ซ้ายสุดอะไรนะ?

อัลกอริทึมการเรียงลำดับคำต่อท้าย (SAIS, KA, daware ของฉันเอง) ต่อท้ายกลุ่มเป็นประเภทต่างๆเพื่อเรียงลำดับ ประเภทพื้นฐานมีสองประเภทคือ: S-typeและL-typeต่อท้าย S-type suffixes เป็นคำต่อท้ายที่น้อยกว่า lexicographically ( S maller) กว่าคำต่อท้ายและL-typeถ้ามันเป็น lexicographically มากกว่า ( L arger) ซ้ายสุดประเภท S ( LMS ชนิด ) เป็นเพียงที่: เป็นประเภท Sต่อท้ายที่นำหน้าด้วยL-ชนิดคำต่อท้าย

สิ่งพิเศษเกี่ยวกับคำต่อท้ายชนิด LMSเหล่านี้คือเมื่อเราจัดเรียงพวกเขาเราสามารถเรียงลำดับคำต่อท้ายอื่น ๆ ทั้งหมดในเวลาเชิงเส้น! มันยอดเยี่ยมใช่ไหม

ความท้าทาย

รับสายคิดว่ามันจะถูกยกเลิกโดยตัวละครพิเศษที่น้อยกว่าตัวละครอื่น ๆ ในสตริงที่ (เช่นเล็กกว่าแม้กระทั่ง null null) เอาท์พุทประเภทการกัดกร่อนการถ่านสำหรับแต่ละคำต่อท้าย

คุณได้อย่างอิสระสามารถเลือกได้ว่าถ่านที่จะใช้สำหรับประเภท แต่ฉันต้องการL, S and *สำหรับL-, S- and LMS-typeตราบเท่าที่พวกเขาทั้งหมดที่พิมพ์ ( 0x20 - 0x7E)

ตัวอย่าง

รับmmiissiissiippiเอาท์พุทสตริง(เมื่อใช้L, S and *):

 LL*SLL*SLL*SLLL

ตัวอย่างแรกLคือเนื่องจากความจริงที่ว่าmmiissiissiippi$มากกว่าพจนานุกรมmiissiissiippi$(ที่$แสดงถึงตัวละครน้อยที่สุดเพิ่ม):

L - mmiissiissiippi$ > miissiissiippi$
L - miissiissiippi$  > iissiissiippi$
* - iissiissiippi$   < issiissiippi     and preceeded by L
S - issiissiippi$    < ssiissiippi$
L - ssiissiippi$     > siissiippi$
L - siissiippi$      > iissiippi$
* - iissiippi$       < issiippi$        and preceeded by L
S - issiippi$        < ssiippi$
L - ssiippi$         > siippi$
L - siippi$          > iippi$
* - iippi$           < ippi$            and preceeded by L
S - ippi$            < ppi$
L - ppi$             > pi$
L - pi$              > i$
L - i$               > $

ตัวอย่างเพิ่มเติม:

"hello world" -> "L*SSL*L*LLL"
"Hello World" -> "SSSSL*SSLLL"
"53Ab§%5qS"   -> "L*SSL*SLL"

เป้าหมาย

ฉันไม่ได้มาที่นี่เพื่อรบกวน Peter Cordes (ฉันจะทำสิ่งนี้ใน stackoverflow บางครั้ง); ฉันขี้เกียจมาก ๆ ดังนั้นนี่เป็นแน่นอน! คำตอบที่สั้นที่สุดเป็นไบต์ชนะ


แก้ไข: ลำดับของตัวอักษรถูกกำหนดโดยค่าไบต์ strcmpนั่นหมายถึงการเปรียบเทียบควรเป็นเช่นซี

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


เคล็ดลับสำหรับเวลาเชิงเส้น:

  1. มันสามารถทำได้ใน 2 ซ้ำไปข้างหน้าขนานหรือในการทำซ้ำย้อนหลังเดียว
  2. สถานะของคำต่อท้ายแต่ละรายการจะขึ้นอยู่กับ 2 ตัวอักษรแรกและประเภทที่สองเท่านั้น
  3. การสแกนอินพุตในทิศทางกลับกันคุณสามารถกำหนด L หรือ S ดังนี้: $t=$c<=>$d?:$t(PHP 7) โดยที่$cchar ปัจจุบันเป็นชนิด$dก่อนหน้าและ$tชนิดก่อนหน้า
  4. ดูของฉันคำตอบ PHP พรุ่งนี้ฉันจะมอบรางวัลให้

นี่คือคำถามแรกของฉัน :) Sandboxมีสอง upvotes และไม่มีความคิดเห็นดังนั้นฉันคิดว่ามันพร้อมที่จะโพสต์ อย่าลังเลที่จะให้คำแนะนำ!
Christoph

อักขระใดบ้างที่สามารถปรากฏในอินพุตได้
Martin Ender

@MartinEnder ทุกตัวอักษรสตริงของคุณรองรับเช่นแม้กระทั่งไบต์ที่ว่างสำหรับc++สตริงสไตล์ คิดว่ามันเป็นข้อมูลไบนารี
Christoph

อะไร*หมายถึง?
Leun Nun

@LeakyNun หมายถึงปัจจัยที่สอดคล้องกันคือประเภท* . left most s-typeA S-type suffix that is preceeded by a L-type suffix.
Christoph

คำตอบ:


7

Haskell , 64 53 48 42 ไบต์

(0!)
k!(x:y)|x:y>y=1:2!y|2>1=k:0!y
_![]=[]

ลองออนไลน์!

Ungolfed ด้วยCharแทนที่จะเป็นInt:

suffixes :: String -> String
suffixes = go 'S'
 where
   go :: Char -> String -> String
   go _ "" = ""
   go lorstar s | s > tail s = 'L' : go '*' (tail s)
                | otherwise  = lorstar : go 'S' (tail s)

อนุญาตให้ใช้ฟังก์ชันที่ไม่ระบุชื่อดังนั้นz=สามารถลบได้
Ørjan Johansen

ฉันแค่อ่าน Haskell ไม่ได้ คุณจะช่วยอธิบายสั้น ๆ ให้ฉันได้ไหม
Christoph

1
@Christoph: goฟังก์ชั่นใช้เวลาสองข้อโต้แย้ง สิ่งแรกคือตัวละครที่แสดงถึงสิ่งที่ควรใช้เพื่ออธิบายSสถานการณ์ ประการที่สองคือสตริง มันจะผ่านสตริงนั้นซ้ำ ๆ ลบอักขระแรกในแต่ละขั้นตอน (นั่นคือสิ่งที่tail) เคล็ดลับคือว่าอาร์กิวเมนต์แรกคือการตั้งค่าให้*เมื่อผลก่อนหน้านี้เป็นLหรือSเป็นอย่างอื่น ด้วยวิธีนี้ในกรณีที่ควรใช้*หรือSควรใช้อาร์กิวเมนต์แรกนั้นโดยตรง หวังว่ามันสมเหตุสมผล
bartavelle

นั่นเป็นความคิดที่ดีทีเดียว! ฉันหวังว่าจะเห็นความคิดที่ชาญฉลาดมากขึ้น :)
Christoph

@ ØrjanJohansenฉันควรเตรียมผลลัพธ์เป็น TIO อย่างไร
bartavelle

6

เยลลี่ ,  25 23 21 20  19 ไบต์

Ṛ;\UỤỤIṠµI2n×ịØDṚ;0

โปรแกรมเต็มรูปแบบที่พิมพ์รายการอักขระโดยใช้:

L: 0
S: 8
*: 9

(เป็นลิงก์จะส่งคืนรายการที่รายการทั้งหมดเป็นอักขระยกเว้นอันสุดท้ายซึ่งเป็นศูนย์)

ลองออนไลน์! หรือดูชุดทดสอบ (พร้อมการแปลงเป็นLS*)

อย่างไร?

Ṛ;\UỤỤIṠµI2n×ịØDṚ;0 - Link: list of characters, s  e.g. "cast"
Ṛ                   - reverse                           "tsac"
  \                 - cumulative reduce by:
 ;                  -   concatenation                   ["t","ts","tsa","tsac"]
   U                - upend (reverse each)              ["t","st","ast","cast"] (suffixes)
    Ụ               - sort indexes by value             [3,4,2,1] (lexicographical order)
     Ụ              - sort indexes by value             [4,3,1,2] (order of that)
      I             - incremental differences           [-1,-2,1] (change)
       Ṡ            - sign                              [-1,-1,1] (comparisons)
        µ           - monadic chain separation, call that x
         I          - incremental differences           [0,2] (only (-1,1) produce 2s)
          2         - literal 2                         2
           n        - not equal?                        [1,0] (indexes of * will be 0)
            ×       - multiply by x (vectorises)        [-1,0,1] (make indexes of *s 0)
              ØD    - decimal yield                     "0123456789"
             ị      - index into (1-indexed & modular)  ['8','9','0']
                Ṛ   - reverse                           ['0','9','8']
                 ;0 - concatenate a zero                ['0','9','8',0]
                    - implicit print                     0980
                    -                              i.e. "L*SL"

คุณจะช่วยเพิ่มคำอธิบายเล็กน้อยสำหรับฉันได้ไหม
Christoph

2
ฉันจะทำแน่นอน - ฉันกำลังคิดเกี่ยวกับกอล์ฟที่เป็นไปได้ก่อน ...
Jonathan Allan


@LeakyNun คุณเป็นคนที่ทำงานออกมาได้อย่างไร! คุณกำลังใช้ข้อผิดพลาดที่นั่นฉันคิดว่า+ในสตริงดูเหมือนว่าจะ vectorise แต่ผลลัพธ์ที่พื้นฐานไม่จริงเยลลี่ iterables แต่สตริง (!) (เช่นลอง+@/L€หรือ+@/L€€หรือ ... )
Jonathan Allan

@JanathanAllan ใช่+สร้างสตริงจริง นี่คือคุณสมบัติที่ไม่มีเอกสารหรือสิ่งที่คุณเรียกว่าบั๊ก
Leun Nun

3

Python 3, 92 87 74 69 65 ไบต์

s=input()
c=1
while s:d=s<s[1:];print(d+(c<d),end='');s=s[1:];c=d

ใช้0สำหรับL, 1สำหรับS, และสำหรับ2 *ตัดสตริงอินพุตด้วยอักขระเครื่องหมายคำพูด ฉันเชื่อว่าสิ่งนี้ได้รับอนุญาตจากการประชุม

ลองออนไลน์!

ตัวอย่างการใช้:

mmiissiissiippi
002100210021000

บันทึก 5 ไบต์ขอบคุณ Leaky Nun, 4 ไบต์ขอบคุณ ovs




3

JavaScript (ES6), 51 45 ไบต์

f=(c,d)=>c&&(d<(d=c<(c=c.slice(1))))+d+f(c,d)

บันทึกแล้ว 6 ไบต์ขอบคุณ @Neil

วิธีแก้ปัญหาแบบเรียกซ้ำสำหรับการออกกำลังกาย

f=(c,d)=>c&&(d<(d=c<(c=c.slice(1))))+d+f(c,d)

console.log(f('mmiissiissiippi')); //LL*SLL*SLL*SLLL   002100210021000
console.log(f('hello world'));     //L*SSL*L*LLL       02110202000
console.log(f('Hello World'));     //SSSSL*SSLLL       11110211000
console.log(f('53Ab§%5qS'));       //L*SSL*SLL         021102100


บันทึก 6 ไบต์:f=(c,d)=>c&&(d<(d=c<(c=c.slice(1))))+d+f(c,d)
Neil

ขอบคุณ @Neil ฉันรู้ว่าต้องมีการเพิ่มประสิทธิภาพที่นั่นที่ไหนสักแห่ง
Rick Hitchcock



1

Haskell , 77 75 ไบต์, เวลาเชิงเส้น

f(a:b:c)|let g"L"|a<b="SL";g"S"|a>b="L*";g d=d++d;d:e=f$b:c=g[d]++e
f _="L"

ลองออนไลน์!

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

สิ่งนี้ใช้การเรียกซ้ำโดยดึงอักขระหนึ่งตัวออกจากจุดเริ่มต้นของสตริง (ประเภทสตริง Haskell เป็นรายการอักขระที่เชื่อมโยงโดยลำพังดังนั้นแต่ละขั้นตอนเหล่านี้จึงเป็นเวลาคงที่)

  • สำหรับสตริงabcโดยที่aและbเป็นอักขระเดี่ยวและcคือสตริงใด ๆ (อาจว่างเปล่า)
    • f ( abc ) = SL e , ถ้าf ( bc ) = L eและa < b ;
    • f ( abc ) = L * e , ถ้าf ( bc ) = S eและa > b ;
    • f ( abc ) = LL e , ถ้าf ( bc ) = L eและab ;
    • ( ABC ) = เอสเอสอีถ้า ( BC ) = S Eและ≤ ข
  • สำหรับสตริงอักขระเดียวa , f ( a ) = L.

1
คุณช่วยอธิบายได้ไหม
R. Kap

โปรดระบุคำอธิบายเพื่อที่ฉันจะสามารถตรวจสอบได้ว่าสิ่งนี้ทำงานในเวลาเชิงเส้น
Christoph

@Christoph เพิ่ม
Anders Kaseorg

@AndersKaseorg ขอบคุณสำหรับการเพิ่ม! น่าเศร้าที่ดูเหมือนว่าค่อนข้างละเอียดเมื่อเทียบกับคำตอบอื่น ๆ ของ Haskell สิ่งนี้จะสามารถเล่นกอล์ฟต่อไปได้S, L and *หรือไม่โดยไม่ใช้
Christoph

1
@Christoph เพื่อให้ชัดเจน[1,1,2,0,1,1,2,0,1,1,2,0,1,1,1]เป็นรายการของตัวเลขหลักเดียวไม่ใช่รายการของตัวอักษรเดี่ยว ในกรณีของฉันฉันคิดว่าการแสดงรายการตัวเลขจะไม่ช่วยฉันไบต์ใด ๆ
Anders Kaseorg

1

Python 2 , 65 55 ไบต์

เวอร์ชันเรียกซ้ำตามคำตอบของ L3viathanใช้012เป็นLS*:

def g(s,d=2):c=s<s[1:];return s and`c+(d<c)`+g(s[1:],c)

ลองออนไลน์!

Python 3 , 65 59 ไบต์

วิธีการแก้ปัญหาซ้ำโดยใช้L, Sและ*:

f=lambda s:s and('LS'[s<s[1:]]+f(s[1:])).replace('LS','L*')

วิ่งผ่านสตริงจากด้านหน้าและแทนที่อินสแตนซ์ทั้งหมดLSด้วยL*

ลองออนไลน์!


1
blah if s else''s and blahบันทึกหกไบต์ ใน Python 2 str(blah)`blah`บันทึกอีกสามไบต์บนโซลูชันที่สอง
Anders Kaseorg

1

PHP, 82 ไบต์, เวลาเชิงเส้น

for($a=$argn;a&$c=$a[$i-=1];$d=$c)$a[$i]=2+$t=$d<=>$c?:$t;echo strtr($a,[13=>12]);

เดินผ่านอินพุตจากขวาไปซ้ายและแทนที่อักขระแต่ละตัวด้วยชนิด

$t=$d<=>$c?:$t

คำนวณประเภทที่กำหนดปัจจุบันและถ่านก่อนหน้า (-1 หรือ 1) ถ้าเท่ากับประเภทจะไม่เปลี่ยนแปลง


+1 สำหรับแนวคิดด้วยstrtr
JörgHülsermann

1

PHP , 70 ไบต์

L = 1, S = 0, * = 2

ต้องการการสนับสนุนหลายไบต์สำหรับ Testcase ล่าสุดที่มี§+3 Bytes mb_substrแทนsubstr

for(;$s=&$argn;$s=$u)$r.=$l=($l&1)+(1&$l^($s>$u=substr($s,1)));echo$r;

ลองออนไลน์!

PHP , 71 ไบต์

L = 1, S = 0, * = 2

for(;$s=&$argn;$s=$u)$r.=+($s>$u=substr($s,1));echo strtr($r,[10=>12]);

ลองออนไลน์!

PHP , 74 ไบต์

for(;$s=&$argn;$s=$u)$r.=SL[$s>$u=substr($s,1)];echo strtr($r,[LS=>"L*"]);

ลองออนไลน์!


$s=&$argnค่อนข้างฉลาด! ผมค่อนข้างแน่ใจว่ามีคำตอบที่ดีแม้ว่า;) หวังว่าคนที่มากับมัน :)
คริสโต

@ Christoph ฉันมีความรู้สึกว่าฉันคิดถึงอะไรบางอย่าง ฉันได้ลองเก็บ LS * สุดท้ายใน varibale แต่มันจะนานกว่า
JörgHülsermann

@ Christoph หมายความว่าคุณชอบงั้นเหรอ? ฉันไม่เห็นจริง ๆ ว่าทำไมตัวอย่างทดสอบครั้งสุดท้ายเป็นเท็จลองออนไลน์!
JörgHülsermann

@Christoph เอาล่ะฉันได้เห็นมันทำไมมันไม่ทำงานสำหรับ testcase สุดท้ายที่ผมต้องใช้mb_substrแทนsubstrถ้าใส่ไม่ได้อยู่ในช่วง ASCII ง่าย จำเป็นหรือไม่ที่จะต้องรองรับการทดสอบครั้งสุดท้าย?
JörgHülsermann

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