Garlandification


38

คำพูดของพวงมาลัย

คำพวงมาลัยเป็นคำที่สามารถเครียดกันเช่นพวงมาลัยเพราะมันจบลงด้วยตัวอักษรเดียวกันจะเริ่มต้นด้วย กลุ่มตัวอักษรเหล่านี้อาจทับซ้อนกัน!

ตัวอย่างเช่นundergroundเป็นคำสั่งพวงมาลัย3เนื่องจากมันเริ่มต้นและสิ้นสุดด้วยอักขระ 3 ตัวundเดียวกัน undergroundergrounderground...วิธีนี้ก็อาจจะเครียดกันเช่น

alfalfaเป็นคำพวงมาลัยด้วย! มันเป็นเรื่องของการสั่งซื้อ 4. alfaมันเริ่มต้นและจบลงด้วย alfalfalfalfaมันสามารถจะเครียดกันเช่นดังนั้น:

กระบวนการที่ฉันเรียก garlandifying คือเมื่อคุณกำหนดลำดับnของคำ garland คุณใช้คำเดิมและเพิ่มส่วนที่จำเป็นเพื่อให้มันวนเป็นพวงมาลัยnครั้ง ดังนั้นตั้งแต่onionเป็นคำสั่ง2คำพวงมาลัยคุณจะใช้เวลาonionสับปิดแรก2จดหมายที่จะได้รับionและเพิ่มที่ท้ายที่สุดเท่าที่จะได้รับ2onionionion

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

สร้างโปรแกรมหรือฟังก์ชั่นที่รับอินพุตจากอินพุตมาตรฐานหรืออาร์กิวเมนต์ของฟังก์ชันแล้วพิมพ์ออกมาหรือส่งกลับคำว่า garlandified

length(word) - 1ทุกคำจะเป็นตัวพิมพ์เล็กและการสั่งซื้อสูงสุดเป็นไปได้สำหรับคำคือ

ตัวอย่าง I / O

"onion"       --> "onionionion"
"jackhammer"  --> "jackhammer"
"abracadabra" --> "abracadabracadabracadabracadabracadabra"
""            --> ""
"zvioz"       --> "zviozvioz"
"alfalfa"     --> "alfalfalfalfalfalfa"
"aaaa"        --> "aaaaaaa"

นี่คือดังนั้นจำนวนไบต์น้อยที่สุดจึงจะชนะ


2
คำตัวอักษร N ใด ๆ ที่ขึ้นต้นด้วยตัวอักษร N ตัวเดียวกับที่ลงท้ายด้วย คำสั่งซื้อสูงสุดที่ควรพิจารณาคืออะไร
feersum

@feersum คำสั่งซื้อสูงสุดคือความยาวของคำ - 1. เพิ่มเข้าไปในโพสต์หลัก
Kade

ฉันต้องพิมพ์พวงมาลัยแค่ไหน? หรือฉันอาจพิมพ์และยกเว้นได้หรือไม่
DeadChex

@DeadChex ไม่ควรมีข้อยกเว้น
Kade

1
@ LuisMendo มันควรใช้กับคำที่ยาวมาก ๆ
Kade

คำตอบ:


12

Pyth, 19 18 ไบต์

+z*>Kf!xz>zT1zl>zK

ลองใช้งานออนไลน์: การสาธิตหรือชุดทดสอบ

คำอธิบาย:

+z*>Kf!xz>zT1zl>zK   implicit: z = input string
     f      1        find the first number T >= 1, which satisfies:
         >zT            all but the first T chars of z
       xz               index of ^ in z
      !                 == 0
    K                store in K
                     the order is length(z) - K
   >K        z       the last K chars
  *                  repeated
              l>zK   len(all but the last K chars) times
+z                   insert z at the beginning

14

Python ขนาด 60 ไบต์

f=lambda s,i=1:s.find(s[i:])and f(s,i+1)or(len(s)-i)*s[:i]+s

หวังว่าจะดีขึ้น แต่ก็ดี ทำงานได้อย่างเรียบร้อยที่นี่ในสถานที่ของs.findnot s.startswith


12

เรติน่า 58 ไบต์

.+
$0#$0
(.*)(.+)#.*\1$
$0#$1#$2-
+`\w#(\w*)-
#$1-$1
#.*-
<empty line>

แต่ละบรรทัดควรไปที่ไฟล์ของตัวเอง แต่คุณสามารถเรียกใช้รหัสเป็นไฟล์เดียวที่มีการ-sตั้งค่าสถานะ

คู่ชดเชยสี่คู่ทำสิ่งต่อไปนี้:

  • ทำซ้ำคำเพื่อให้เราสามารถค้นหาการทับซ้อนได้เช่นกัน
  • ต่อท้ายคำแยกตามorderจำนวนตัวอักษร
  • ผนวกส่วนสุดท้ายorderครั้ง
  • เก็บคำเดิมและส่วนที่ต่อท้ายและวางทุกอย่างอื่น

สตริงระบุสำหรับตัวอย่างonion:

onion
onion#onion
onion#onion#on#ion-
onion#onion##ion-ionion
onionionion

10

Haskell, 64 ไบต์

g s=[b>>a|(a,b)<-map(`splitAt`s)[1..],and$zipWith(==)s b]!!0++s

แบบทดสอบ:

λ: g "onion"       == "onionionion"
True
λ: g "jackhammer"  == "jackhammer"
True
λ: g "abracadabra" == "abracadabracadabracadabracadabracadabra"
True
λ: g ""            == ""
True
λ: g "zvioz"       == "zviozvioz"
True
λ: g "alfalfa"     == "alfalfalfalfalfalfa"
True
λ: g "aaaa"        == "aaaaaaa"
True

10

Java, 160 157 bytes

static void g(String s){int i=s.length(),o;for(String p=s;i-->0;)if(s.endsWith(s.substring(0,i))){for(o=i;o-->0;)p+=s.substring(i);System.out.print(p);i=0;}}

Input / Output:

 g("abracadabra"); --> "abracadabracadabracadabracadabracadabra"

เว้นระยะและแท็บเพื่อให้อ่านง่าย:

static void g(String s){
int i=s.length(),o;
for(String p=s;i-->0;)
    if(s.endsWith(s.substring(0,i))){
        for(o=i;o-->0;)
            p+=s.substring(i);
        System.out.print(p);
        i=0;
    }
}

ยินดีต้อนรับข้อเสนอแนะ


ในฐานะที่เป็นโน้ตถึงตัวฉันเองสตริง ops สามารถย้ายไปอยู่ในลูป for เพื่อบันทึกไบต์หรือสองในเซมิโคลอน
DeadChex

ทำไมไม่ทำi=0;?
overactor

@overactor อยู่ที่ไหน เหตุผลที่ฉันใช้ความยาวเป็นเพราะฉันต้องการสตริงเต็มแล้วฉันต้องการย้ายไปที่ไม่มีมันด้วย substring ฉันไม่คิดว่าฉันสามารถหลีกเลี่ยงการใช้มันในวิธีนี้และจะใช้บทลงโทษ byte สำหรับมัน
DeadChex

2
ฉันตั้งใจจะแยกวงออกจากวงนอก
overactor

8

Sed: 87 84 ตัวอักษร

(83 รหัสตัวอักษร + 1 ตัวเลือกบรรทัดคำสั่ง)

h
s/(.*)./& \1/
T
s/(.+) \1.*/ \1 \1/
t
g
q
:
s/^([^ ]+)(.*)[^ ]$/\1 \1\2/
t
s/ //g

วิ่งตัวอย่าง:

bash-4.3$ sed -r 'h;s/(.*)./& \1/;T;s/(.+) \1.*/ \1 \1/;t;g;q;:;s/^([^ ]+)(.*)[^ ]$/\1 \1\2/;t;s/ //g' <<< 'underground'
undergroundergroundergrounderground

upvote อัตโนมัติของคำตอบ sed ;-) ทำตามเคล็ดลับนี้เพื่อดร็อป 2 ตัวอักษรจากคำจำกัดความของฉลากและสาขา
Digital Trauma

พยายามมาแล้ว แต่ฉันเกรงว่าคำแนะนำนั้นมีไว้สำหรับกรณีที่คุณไม่มีรหัสข้ามไปที่ส่วนท้ายของรหัสเท่านั้น [หลังจากนี้…] ตกลงคิดอีกครั้งทำไมฉันพยายามประมวลผลอินพุตหลายบรรทัดพร้อมกัน
จัดการ

7

CJam, 24 23 ไบต์

q_:Q,{~)Q>Q\#!},W>~_Q>*

q_:Q                       e# Read the input, take a copy and store it in Q too
    ,{        },           e# Take the length of the input and filter [0 .. len - 1] array
      ~)                   e# Same as number * -1
        Q>                 e# Take last number characters. Call this string S
          Q\#!             e# See if Q starts with S. After the filter, we will only have
                           e# those numbers from [0 .. len - 1] array which are valid orders
                W>~        e# Take the last order number, if exists.
                   _Q>*    e# Garlandify the input order times.

เพื่อเริ่มต้นกับบางสิ่ง ..

ลองออนไลน์ได้ที่นี่


5

Matlab: 97 89 82 ไบต์

ฟังก์ชั่นที่ใช้การแสดงออกปกติกับ lookbehind และกลุ่มการจับ

function t=f(s)
n=sum(regexp(s,'(.*$)(?<=^\1.+)'))-1;t=[s(repmat(1:n,1,end-n)) s];

ที่sumจำเป็นในการจัดการอินพุตว่างสตริง (แปลง[]เป็น0)

ตัวอย่าง:

> f('onion'), f('jackhammer'), f('abracadabra'), f(''), f('zvioz'), f('alfalfa'), f('aaaa')
ans =
onionionion
ans =
jackhammer
ans =
abracadabracadabracadabracadabracadabra
ans =
   Empty string: 1-by-0
ans =
zviozvioz
ans =
alfalfalfalfalfalfa
ans =
aaaaaaa

4

REGXY, 53 49 ไบต์

ใช้REGXYซึ่งเป็นภาษาที่ใช้ในการทดแทน regex

//$'#/
/.(.+)#\1\K/#/
a/(#).(.*#)|#.*/$'$1$2/
//a

ภาพรวม: มีการใช้นิพจน์ทั่วไปจำนวนหนึ่ง ตัวอย่างการรันจะมีลักษณะดังนี้:

onion (input)
onion#onion (line 1 regex)
onion#on#ion (line 2 regex - find the repeated section and separate with #)
onionion#n#ion (line 3 regex - the length of the middle token is the garland order, remove a character and append the third token onto the original string on the left)
onionionion##ion (line 4 regex is a pointer to line 3 - repeat the previous again)
onionionion##ion (line 4 regex is a pointer to line 3 - strip everything after and including the #)

คำอธิบายโดยละเอียด ต่อไปนี้เป็นรายการแยกตามบรรทัดของ regexes:

//$'#/

นี่เป็นการทดแทน regex ซึ่งตรงกับสตริงว่างอันแรก (เช่นการเริ่มต้นของสตริง) และแทนที่มันด้วยทุกอย่างทางด้านขวาของการแข่งขัน ( $') ตามด้วยแฮช ยกตัวอย่างเช่นมันจะเปิดเข้าไปoniononion#onion

/.(.+)#\1\K/#/

บรรทัดนี้จะค้นหาส่วนที่ทับซ้อนกันโดยค้นหากลุ่มของอักขระที่อยู่ตรงหน้า # ( (.+)) ซึ่งอยู่ด้านเดียวกันของ # ( \1) \ K หมายถึง 'ลืมว่าฉันจับคู่กับอะไรก็ได้' หมายความว่าจะไม่ถูกแทนที่ในการเปลี่ยนตัว นี้ได้อย่างมีประสิทธิภาพที่นี้หมายถึงเราเพียงแค่เพิ่ม # ไปยังตำแหน่งที่ทับซ้อนกันหลังจากที่ได้รับพบว่าหันเข้าonion#oniononion#on#ion

a/(#).(.*#)|#.*/$'$1$2/

เริ่มต้น 'a' เป็นเพียงฉลากสำหรับ regex หลังจากนี้เราจะพบ # แรกตามด้วยอักขระตัวเดียว ( .) และจับทุกอย่างหลังจากนี้จนถึง # ถัดไป ( .*#) เราแทนที่สิ่งนี้ด้วยทุกสิ่งทางด้านขวาของการจับคู่คือโทเค็นสุดท้าย ($ '), ตามด้วย # ( $1), ตามด้วยโทเค็นที่สองน้อยกว่าอักขระ (เราถือว่านี่เป็นตัวนับลดแต่ละการทำซ้ำ) ในกรณีของหัวหอม # # เกี่ยวกับไอออนทั้งสองราชสกุลเรา backreference บนจะแสดงในวงเล็บและส่วนทั้งการแข่งขัน regex onion|(#)o(n#)|ionอยู่ระหว่างท่อ: จากนั้นเราจะแทนที่บิตที่เราจับคู่ (ระหว่างไพพ์) ด้วย$'(ทุกอย่างทางด้านขวาของการแข่งขันคือ 'ไอออน') จากนั้น $ 1 (the #) จากนั้น $ 2 (n #) ซึ่งหมายถึงเราท้ายด้วยonion|(ion)(#)(n#)|ion(วงเล็บแสดง โทเค็นทั้งสามในสตริงการแทนที่)

หาก regex ไม่ตรงกันในการสลับครั้งแรก (ทุกอย่างก่อนไพพ์) เราจะต้องลดตัวนับของเราเป็นศูนย์ซึ่งหมายความว่าไม่มีอักขระภายในโทเค็นที่สอง เรามองไปที่ส่วนที่สองของลวดลาย#.*แทน นี้ก็แทนที่ทุกอย่างหลังจากที่ # $'$1$2ครั้งแรกกับ เนื่องจากไม่มีการอ้างอิงย้อนหลังที่สร้างขึ้นโดยการสลับนี้และไม่มีสิ่งใดอยู่ทางขวาของการแข่งขัน ( .*แมตช์จนถึงจุดสิ้นสุดของสตริง) เราจึงยุติการแข่งขันและส่งคืนผลลัพธ์

//a

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


3

jq 1.5: 91 ตัวอักษร

(ตัวเลือกบรรทัดคำสั่งรหัส 87 อักขระ + 4 อักขระ)

.+. as$t|[range(1;length)|select($t[:.]==$t[-.:])]|(max//0)as$i|[range($i)|$t[$i:]]|add

วิ่งตัวอย่าง:

bash-4.3$ jq -R -r -f judy.jq <<< 'underground'
undergroundergroundergrounderground

3

อาร์เอส , 51 48 ไบต์

(.+)/\1 \1
(.+)(.+) .+\1$/\1(\2)^^((^^\1_))
 .*/

ลองดู RETINA และ SED !!!!! ;)

ตัด 3 ไบต์ด้วย @randomra

กรณีสาธิตและการทดสอบสด

โปรดทราบว่าjackhammerกรณีทดสอบไม่ได้มี มีข้อบกพร่องในการจัดการช่องว่างในเว็บอินเตอร์เฟสที่ทำให้พิมพ์งานไม่ถูกต้อง เวอร์ชันออฟไลน์ของการrsจัดการอย่างถูกต้อง

รุ่น 51 ไบต์:

(.+)/\1 \1
^(.+)(.+) (.+)\1$/\1(\2)^^((^^\1_))
 .*/

ตัวอย่างสดและกรณีทดสอบสำหรับต้นฉบับ


@randomra อัปเดตแล้ว ขอบคุณ!
kirbyfan64sos

2

JavaScript (ES6), 95 ไบต์

f=s=>{for(e=i=s.length;i&&e;)s+=s.slice(--i).repeat(!(e=!s.endsWith(s.slice(0,i)))*i);return s}

การสาธิต

Firefox เท่านั้นตอนนี้:

f = s => {
  for (e = i = s.length; i && e;) s += s.slice(--i).repeat(!(e = !s.endsWith(s.slice(0, i))) * i);
  return s
}

console.log = x => X.innerHTML += x + '\n';

console.log(f('onion'));
console.log(f('jackhammer'));
console.log(f('abracadabra'));
console.log(f(''));
console.log(f('zvioz'));
console.log(f('alfalfa'));
console.log(f('aaaa'));
<pre id=X></pre>


2

JavaScript (ES6), 82 ไบต์

g=(s,i=t=s.length)=>s.endsWith(c=s.slice(0,--i))?c+s.slice(i-t).repeat(i+1):g(s,i)

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

ตัวอย่าง

g=(s,i=t=s.length)=>s.endsWith(c=s.slice(0,--i))?c+s.slice(i-t).repeat(i+1):g(s,i)

console.log(g('onion'));
console.log(g('jackhammer'));
console.log(g('abracadabra'));
console.log(g(''));
console.log(g('zvioz'));
console.log(g('alfalfa'));
console.log(g('aaaa'));


1

CoffeeScript + ES6, 77 ไบต์

เช่นเดียวกับคำตอบ JavaScript ของฉัน

f=(s,e=i=s.length)->s+=s[i..].repeat !(e=!s.endsWith s[...i])*i while--i&&e;s

0

C

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
    char *str   = NULL;
    char *p     = NULL;
    int len     = 0 ;
    int i       = 0;
    int j       = 0;
    int k       = 0;
    int loop    = 0;

    if (argc == 1 )
        return 0;

    str = argv[1];
    len = strlen(str);

    if (len %2) {
        loop = len/2 + 1;
    }
    else {
        loop = len/2;
    }


    p = &str[len/2];
    for (i = 0; i < loop ; i++) {
        if (str[k] == *(p++)) {
            k++;
        }
        else
            k = 0;
    }

    printf("k = %d\n", k);
    printf("%s", str);
    p = &str[k];
    for (j =0; j < k ; j++) {
        printf("%s", p);
    }
    return 0;
}

Golfed: 195 ไบต์ - GCC

main(int c,char**a){
char *s=a[1],*p;int i=0,j=0,k=0,z,l=strlen(a[1]);
z=l%2?-~(l/2):l/2;p=&s[l/2];
for(;i<z;i++)k=s[k]==*(p++)?-~k:0;
printf("k=%d\n",k);puts(s);p= &s[k];
for(;j<k;j++)puts(p);}

5
ยินดีต้อนรับสู่การเขียนโปรแกรมปริศนาและรหัสกอล์ฟ! คำถามนี้คือ code golf ดังนั้นฉันขอแนะนำให้คุณ "golf" โค้ดของคุณโดยลบ whitespace ที่ไม่จำเป็นออก ฯลฯ จากนั้นให้นับจำนวนไบต์ของโค้ดของคุณในชื่อโพสต์ของคุณพร้อมกับภาษา
lirtosiast

1
เข้าใจแล้ว. ขอบคุณสำหรับทิศทาง ฉันจะเก็บไว้ในใจในครั้งต่อไป
Alam

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

ไม่ได้intอยู่ใน (รุ่นเก่าเพียงพอ) C หรือไม่
Reinstate Monica

0

Groovy 75 57 55 ไบต์

f={w->x=w;w.find{x-=it;!w.indexOf(x)};w+(w-x)*x.size()}

น่าอัศจรรย์ว่าการกลับมาหาบางสิ่งในวันถัดไปสามารถช่วยได้

Ungolfed:

f = {w ->

//Set x equal to w
    x=w

//Loop through the characters of w until we return true
    w.find {

//set x equal to x minus the first instance of the current character, i.e.     the word minus the first character
        x-=it

//Returns the index of the first occurance of the string of chars x, when this is 0 (false) we want to return true, so negate it
        !w.indexOf(x)
    }

//When we've escaped the loop, if we've found a match return the word plus the word minus the match multiplied by the lengh of the match.
    w+(w-x)*x.size()     
}

-1

ในกรณีที่มีคนต้องการรหัสใน JS เพื่อทดสอบ หมายเหตุ: ฉันสำรวจสตริงจากปลายเพื่อเพิ่มประสิทธิภาพ:

"use strict";

var garlandify = function(inputString){
    var stringLength = inputString.length;  
    var savedString = inputString;

    for( var i=1; i<stringLength; i++ ){
         var endIndex = Math.abs(i) * -1;       
         if( inputString.startsWith( inputString.substr(endIndex) ) ){
              for( var j=1; j<=i; j++){
                  savedString += inputString.substr(i, stringLength );
              }
              console.log(savedString);         
         }  
    }
};

garlandify("onion");

4
ยินดีต้อนรับสู่การแลกเปลี่ยน Programming Puzzles & Code Golf stack! คุณไม่จำเป็นต้องกังวลเกี่ยวกับประสิทธิภาพเลยสำหรับการเขียนโค้ดกอล์ฟเพียงแค่ความยาวของโปรแกรมของคุณ ดังนั้นเวอร์ชั่นที่ช้าและไม่มีประสิทธิภาพอาจจะดีที่สุดในที่นี้ (มันสามารถเปลี่ยนแปลงได้อย่างสดชื่นจาก "งานจริง"!) ดังนั้นเอาช่องว่างที่ไม่จำเป็นและใช้ชื่อตัวแปรตัวอักษรเดียว - อ่านแล้วเคล็ดลับสำหรับการเล่นกอล์ฟใน JavaScript ฉันคิดว่ามีหลายสิ่งที่คุณสามารถทำได้ในการตีกอล์ฟ - แต่เราชอบที่จะเห็นเวอร์ชันที่แสดงความคิดเห็นที่ไม่ดีถ้าหากอัลกอริทึมของคุณฉลาด มีความสุข!
Toby Speight
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.