Text compression

19

2

With the given text below, there are some words in the text that repeats several times in the text. Use any programming language to write a short code that compresses the text to display it. Or in other words, use the smallest number of bytes to display the text.
The Text is:

Peter Piper picked a peck of pickled peppers.
A peck of pickled peppers Peter Piper picked.
If Peter Piper picked a peck of pickled peppers,
Where's the peck of pickled peppers Peter Piper picked?

Monolica

Posted 2018-10-13T15:50:04.980

Reputation: 1 101

6I'm honestly surprised this didn't get closed as a dupe of that Rick-Roll question. Are we not doing that anymore? – Jo King – 2018-10-15T12:00:37.503

1@JoKing it is a different string. A little variety on the same challenge can be fun sometimes. – moonheart08 – 2018-10-15T17:23:32.820

@moonheart08 pretty sure that point was shot down in meta. – Magic Octopus Urn – 2018-10-16T18:34:23.103

Answers

9

R, 106 bytes

"["=gsub
cat(1["Peter Piper picked",2[" peck of pickled peppers","1 a2.
A2 1.
If 1 a2,
Where's the2 1?"]])

Try it online!

J.Doe

Posted 2018-10-13T15:50:04.980

Reputation: 2 379

1That is a very clever use of aliasing!! – Giuseppe – 2018-10-13T22:45:46.940

1

Great solution ! It beats also the memCompress approach 47+79=126 bytes

– digEmAll – 2018-10-14T08:57:26.627

1

This idea saved me another byte here as well!

– Giuseppe – 2018-10-15T14:10:14.943

Wow, I didn't spot that golf. That's really nice. – J.Doe – 2018-10-15T14:15:17.517

8

Jelly,  80 73 72 68 67 61  57 bytes

“¡ŀṪ]ṃ{yṁ“Ñ3$ṘW5Ḍż⁸¢Hŀ“³ḌM“¡FỊİg“ÑɲʋØƥþƈƘ}“ṣɠ»“Ƙ9~ḷ’ṃFḊ”?

Try it online!

How?

“...“...“...“...“...“...»“Ƙ9~ḷ’ṃFḊ”? - Main Link: no arguments
“...“...“...“...“...“...»            - list of compressed strings
                                     -   = [" Peter Piper picked",
                                     -      " peck of pickled peppers",
                                     -      ".\nA",
                                     -      ".\nIf",
                                     -      ",\nWhere's the",
                                     -      " a"]
                         “Ƙ9~ḷ’      - base 250 literal X = 2331781969
                               ṃ     - base decompress - i.e. use the list of strings as if
                                     -   they were the digits [1,2,3,4,5,0]
                                     -   X in base 6 is [1,0,2,3,2,1,4,1,0,2,5,2,1], so:
                                     -   [" Peter Piper picked",
                                     -    " a",
                                     -    " peck of pickled peppers",
                                     -    ".\nA"," peck of pickled peppers",
                                     -    " Peter Piper picked",
                                     -    ".\nIf",
                                     -    " Peter Piper picked",
                                     -    " a",
                                     -    " peck of pickled peppers",
                                     -    ",\nWhere's the",
                                     -    " peck of pickled peppers",
                                     -    " Peter Piper picked"]
                                F    - flatten
                                 Ḋ   - dequeue (remove the leading space)
                                  ”? - literal '?' character (causes print of previous)
                                     - implicit print (of the '?' character)

Jonathan Allan

Posted 2018-10-13T15:50:04.980

Reputation: 67 804

5

JavaScript (SpiderMonkey), 114 bytes

print(`0 a1.
A1 0.
If 0 a1,
Where's the1 0?`.replace(/\d/g,n=>+n?' peck of pickled peppers':'Peter Piper picked'))

Try it online!

I would claim this answer is from ovs, anyway, 19 bytes saved.

Thanks Arnauld, saves 3 bytes.

tsh

Posted 2018-10-13T15:50:04.980

Reputation: 13 072

1114 bytes. – Arnauld – 2018-10-13T17:29:18.707

5

Bubblegum, 73 71 bytes

00000000: 0b48 2d49 2d52 08c8 2c00 9205 99c9 d9a9  .H-I-R..,.......
00000010: 290a 890a 05a9 c9d9 0af9 6960 819c d414  ).........i`....
00000020: 20bf 0028 5fac c7e5 884b 4a01 d31c 3d2e   ..(_....KJ...=.
00000030: cf34 0552 8cd7 e10a cf48 2d4a 552f 5628  .4.R.....H-JU/V(
00000040: c948 25c1 227b 00                        .H%."{.

Try it online!

ovs

Posted 2018-10-13T15:50:04.980

Reputation: 21 408

2How did you shave off bytes of a bubblegum answer? – Laikoni – 2018-10-13T21:15:07.127

2@Laikoni the original 73 bytes answer was created using gzip on the highest compression level (-9) plus some metadata shaving using head and tail, the 71 byter is generated using zopfli, which I initially forgot about. Zopfli usually creates shorter DEFLATE streams. – ovs – 2018-10-13T21:24:48.130

Yeah, I've tried up to 5,000,000 iterations on zopfli, it couldn't find anything past the 71-byte one on iteration 3109. – LegionMammal978 – 2018-10-13T22:30:40.920

4

Jelly, 64 60 58 57 bytes

“¡ŀṪ]ṃ{yṁ“Ñ3$ṘW5Ḍż⁸¢Hŀ»j⁾ a,Ṛẋ2ż“³ḌM“¡FỊİg“ÑɲʋØƥþƈƘ}»FḊ”?

Try it online!

Dennis

Posted 2018-10-13T15:50:04.980

Reputation: 196 637

Wow, surprisingly similar to another answer, with the same language and same byte count. I don't actually know what's happening in this language, so is the code basicically the same? – tox123 – 2018-10-14T22:14:15.277

1A lot of the overlap in the code is the identical compressed strings, which is not surprising. – Misha Lavrov – 2018-10-14T23:34:58.527

1@tox the two programs are currently not working in the same way (although both of us have used similar ideas as each other in the history of revisions). This one is using compressed string lists (“...“...») to form most of the four lines and then interleaving (ż) with the less repetitive parts (like ',\nIf'), again with compressed string lists; you can see how mine works from the description. – Jonathan Allan – 2018-10-15T12:31:22.340

4

Python 2, 115 bytes

a="Peter Piper picked"
b=" peck of pickled peppers"
print a,"a%s.\nA"%b+b,a+".\nIf",a,"a%s,\nWhere's the"%b+b,a+"?"

Try it online!

Prints multiple commas-separated strings to put spaces in between them.


Python 3, 115 bytes

print("1 a2.\nA2 1.\nIf 1 a2,\nWhere's the2 1?".translate({49:"Peter Piper picked",50:" peck of pickled peppers"}))

Try it online!

Python 3's translate does the heavy lifting. Using non-printable characters with single-digit ASCII value should save two bytes.

xnor

Posted 2018-10-13T15:50:04.980

Reputation: 115 687

1exit saves 1 byte for the Python 3 program. – Jonathan Allan – 2018-10-14T20:14:44.890

3

Bash, 99

  • 4 bytes saved thanks to @manatwork.
echo "${P=Peter Piper picked} a${p= peck of pickled peppers}.
A$p $P.
If $P a$p,
Where's the$p $P?"

Try it online!

Digital Trauma

Posted 2018-10-13T15:50:04.980

Reputation: 64 644

3

You could move the variable declarations to their first usages with assign default value parameter expansions: Try it online!.

– manatwork – 2018-10-13T21:26:50.310

1

@manatwork Wow, I had no idea you could do that. Pretty cool to get under 100 - Thanks! This technique would make a good bash tips answer.

– Digital Trauma – 2018-10-14T02:08:17.887

2

V, 99 87 bytes

-12 bytes: turns out 2 substitutions are shorter which is basically the same as everyone else's solution (except Bubblegum?)

i1 a0.
A0 1.
If 1 a0,
Where's the0 1?Í0/ peck of pickled peppers
Í1/Peter Piper picked

Try it online!

ბიმო

Posted 2018-10-13T15:50:04.980

Reputation: 15 345

2

Java (JDK), 123 bytes

v->"".format("%s a%s.%nA%2$s %1$s.%nIf %1$s a%2$s,%nWhere's the%2$s %1$s?","Peter Piper picked"," peck of pickled peppers")

Try it online!

Olivier Grégoire

Posted 2018-10-13T15:50:04.980

Reputation: 10 647

Are you allowed to take a required argument like that? – Quintec – 2018-10-15T11:50:18.317

2

@Quintec Yes, if the input is unused

– Jo King – 2018-10-15T11:58:12.047

2

Python 3, 120 117 116 bytes

a,b="Peter Piper picked"," peck of pickled peppers"
exit(f"{a} a{b}.\nA{b} {a}.\nIf {a} a{b},\nWhere's the{b} {a}?")

Format strings were shorter than addition(129 bytes) and a join(140 bytes).

-3 thanks to Jo King, -1 thanks to Jonathan Allen

Syfer Polski

Posted 2018-10-13T15:50:04.980

Reputation: 185

1

That's not a format string. That's a format string. (117 bytes)

– Jo King – 2018-10-14T02:16:24.500

1Programs may output to STDERR, so save 1 by replacing print with exit. – Jonathan Allan – 2018-10-14T20:12:50.780

2

Twig, 105 bytes

This uses a simple replacement to fill in the gaps.

Twig's replace() filter allows you to define the values to replace as the keys of an hash. Luckly, it also works with arrays, as they have numerical keys.

{{"0a1.
A1 0.
If 0 a1,
Where's the1 0?"|replace(["Peter Piper picked"," peck of pickled peppers"])|raw}}

The |raw is needed to avoid escaping, which turned Where's into Where's.

You can try it on https://twigfiddle.com/phqpts


Since this is compiled down to PHP, the equivalent for PHP would be:

<?php
    $array = array("Peter Piper picked", " peck of pickled peppers");
    $string = "0 a1.
A1 0.
If 0 a1,
Where's the1 0?";

    echo str_replace(array_keys($array), $array, $string);

Which can be shortened significatively.

Ismael Miguel

Posted 2018-10-13T15:50:04.980

Reputation: 6 797

2

Ruby, 104 bytes

/ a/=~$a="Peter Piper picked a peck of pickled peppers"
puts"#$a.
A#$' #$`.
If #$a,
Where's the#$' #$`?"

Try it online!

G B

Posted 2018-10-13T15:50:04.980

Reputation: 11 099

1

sed, 101 100 bytes

s/^/0 a1.\nA1 0.\nIf 0 a1,\nWhere's the1 0?/
s/0/Peter Piper picked/g
s/1/ peck of pickled peppers/g

Try it online!

-1 byte thanks to @DigitalTrauma

Logern

Posted 2018-10-13T15:50:04.980

Reputation: 845

Replace .* with ^ to save a byte – Digital Trauma – 2018-10-14T02:10:00.160

1

///, 86 bytes

/1/Peter Piper picked//2/ peck of pickled peppers/1 a2.
A2 1.
If 1 a2,
Where's the2 1?

Try it online!

Jo King

Posted 2018-10-13T15:50:04.980

Reputation: 38 234

1

C (gcc), 123 bytes

f(){printf("%s a%s.\nA%2$s %1$s.\nIf %1$s a%2$s,\nWhere's the%2$s %1$s?","Peter Piper picked"," peck of pickled peppers");}

Try it online!

gastropner

Posted 2018-10-13T15:50:04.980

Reputation: 3 264

1

Clean, 166 bytes

import StdEnv,Text;f="peck of pickled";g="picked";u="peppers";p="Peter Piper";s=join" "[p,g,"a",f,u+".\nA",f,u,p,g+".\nIf",p,g,"a",f,u+",\nWhere's","the",f,u,p,g+"?"]

Try it online!

Οurous

Posted 2018-10-13T15:50:04.980

Reputation: 7 916

1

jq, 110 characters

(106 characters code + 4 characters command line options)

"1 a2.
A2 1.
If 1 a2,
Where's the2 1?"|gsub("1";"Peter Piper picked")|gsub("2";" peck of pickled peppers")

Sample run:

bash-4.4$ jq -nr '"1 a2.
A2 1.
If 1 a2,
Where'"'"'s the2 1?"|gsub("1";"Peter Piper picked")|gsub("2";" peck of pickled peppers")'
Peter Piper picked a peck of pickled peppers.
A peck of pickled peppers Peter Piper picked.
If Peter Piper picked a peck of pickled peppers,
Where's the peck of pickled peppers Peter Piper picked?

Try it online!

manatwork

Posted 2018-10-13T15:50:04.980

Reputation: 17 865

1

SQL Server, 211

declare @a char(18)='Peter Piper picked'
declare @b char(24)=' peck of pickled peppers'
declare @c char=char(10)
print @a+' a'+@b+'.'+@c+'A'+@b+' '+@a+'.'+@c+'If '+@a+' a'+@b+','+@c+'Where''s the'+@b+' '+@a+'?'

db<>fiddle

SeanC

Posted 2018-10-13T15:50:04.980

Reputation: 1 117

Nice solution! A few ways to improve: for multiple variables use a comma instead of restating declare; use an actual line break in the string instead of char(10), in fact you can put the line breaks directly in the print statement and eliminate @c entirely. Pick your most-used variable and use @ by itself (its valid!) – BradC – 2018-10-15T17:21:26.787

1

T-SQL, 137 bytes

SELECT p+a+k+'.
A'+k+' '+p+'.
If '+p+a+k+',
Where''s the'+k+' '+p+'?'
FROM(SELECT'Peter Piper picked'p,' a'a,' peck of pickled peppers'k)b

That last return before the FROM is for readability only, the rest are part of the string concatenation.

Different method than SeanC's SQL solution.

BradC

Posted 2018-10-13T15:50:04.980

Reputation: 6 099

1

Stax, 60 56 bytes

╣lF╤╨┴+Y╟W╪▄,○F«↑•L°T»`┼◄ü√}x![Ñ$Θ☼²qσQ¼▬ôZ¡▄╙╥⌂å╛►¶▓&╗s

Run and debug it

recursive

Posted 2018-10-13T15:50:04.980

Reputation: 8 616

1Here's one byte shorter unpacked, and this one seems to be making a profound statement about existence. – Khuldraeseth na'Barya – 2019-08-23T15:53:27.160

"i am. Am i. If i am, Where's them i?" I can't stop laughing. This is gold. – recursive – 2019-08-23T17:50:58.220

Descartes ain't not nothin' on me. – Khuldraeseth na'Barya – 2019-08-23T18:05:32.513

0

Kotlin, 150 bytes

var s="Peter Piper picked"
var z=" peck of pickled peppers"
var v=s+" a"+z
var x=z+" "+s
print(v+".\n"+"A"+x+".\n"+"If "+v+",\n"+"Where's the "+x+"?")

Try it online!

Syed Hamza Hassan

Posted 2018-10-13T15:50:04.980

Reputation: 129

0

Retina 0.8.2, 85 bytes


1 a0.¶A0 1.¶If 1 a0,¶Where's the0 1?
1
Peter Piper picked
0
 peck of pickled peppers

Try it online! Same idea as everyone else.

Neil

Posted 2018-10-13T15:50:04.980

Reputation: 95 035

0

PHP, 107 bytes

<?=($a="Peter Piper picked")." a".($b=" peck of pickled peppers").".
A$b $a.
If $a a$b,
Where's the$b $a?";

Try it online!

Luis felipe De jesus Munoz

Posted 2018-10-13T15:50:04.980

Reputation: 9 639

Missing a point in the first line. – G B – 2018-10-15T10:11:34.597

Use comma instead of concatenation to save 4 bytes: <?=$a=...," a",$b=...,... – Titus – 2018-10-15T14:07:29.437

0

Red, 116 bytes

prin rejoin[a:"Peter Piper picked"" a"b:" peck of pickled peppers"".^/A"b" "a".^/If "a" a"b",^/Where's the"b" "a"?"]

Try it online!

Explanation:

The job is done by the rejoin funcion, which reduces and joins a block of values.

prin rejoin [                      ; print the reduced (evaluated) and joined block
    a: "Peter Piper picked"        ; save the text to a
    " a"                           ; literal " a"
    b: " peck of pickled peppers"  ; save the text to b
    ".^/A"                         ; literal newline followed by "A"
    b                              ; " peck of pickled peppers" 
    " "                            ; literal " "
    a                              ; "Peter Piper picked"
    ".^/If "                       ; literal ".^/If "
    a                              ; "Peter Piper picked"
    " a"                           ; literal " a"
    b                              ; " peck of pickled peppers" 
    ",^/Where's the"               ; literal "," folowwed by a newline by "Where's the"  
    b                              ; " peck of pickled peppers"      
    " "                            ; literal " "
    a                              ; "Peter Piper picked" 
    "?"                            ; literal "?"
]

Galen Ivanov

Posted 2018-10-13T15:50:04.980

Reputation: 13 815

0

J, 121 bytes

echo('1 a2.',CR,'A2 1.',CR,'If 1 a2,',CR,'Where''s the2 1?')rplc('1';'Peter Piper picked';'2';' peck of pickled peppers')

Try it online!

Galen Ivanov

Posted 2018-10-13T15:50:04.980

Reputation: 13 815

0

Powershell, 99 101 bytes

$a='Peter Piper picked'
$b=' peck of pickled peppers'
"$a a$b.
A$b $a.
If $a a$b,
Where's the$b $a`?"

mazzy

Posted 2018-10-13T15:50:04.980

Reputation: 4 832

1Shouldn't $a='Peter Piper picked' ? – wooshinyobject – 2018-10-16T15:56:38.273

1

It appears as though the space in the $b makes your submission both longer and invalid (TIO).

– Jonathan Frech – 2018-10-16T16:22:15.737

1Furthermore, I think you are missing a [...]Peter Piper picked? at your output's end. – Jonathan Frech – 2018-10-16T16:23:58.150

0

C# (.NET Core), 123 118 116 bytes

v=>@"0 a1.
A1 0.
If 0 a1,
Where's the1 0?".Replace("0","Peter Piper picked").Replace("1"," peck of pickled peppers")

Try it online!

Inspired by @Olivier Grégoire's java answer

5 bytes saved by @sebbs

aloisdg moving to codidact.com

Posted 2018-10-13T15:50:04.980

Reputation: 1 767

0

05AB1E, 78 76 74 72 bytes

’0 a1.
A10.
If0 a1,
W€Î's €€10?’TS.•1~¼ ¿•“±æ€‚ ÿÇì“'p0ǝ„íδŒ™„r¾Ð«‚ðì:¦

Try it online.

Explanation:

’0 a1.
A10.
If0 a1,
W€Î's €€10?’              # String "0 a1.\nA10.\nIf0 a1,\nWhere's the10?"
TS                        # 10 to digits: ["1","0"]
.•1~¼ ¿•                  # String "pickled"
        “±æ€‚ ÿÇì“        # String "neck of ÿ pepper", where the "ÿ" will 
                          # automatically be replaced with the top value of the stack
                  'p0ǝ    # Replace the character at index 0 with a "p":
                          #  "peck of pickled pepper"
„íδŒ                     # String "peter pipe"
     ™                    # Titlecased: "Peter Pipe"
      „r¾Ð                # String "r picked"
          «               # Merge them together: "Peter Piper pickled"
           ‚              # Pair them together:
                          #  ["peck of pickled pepper","Peter Piper pickled"]

            ðì            # Prepend a space before each:
                          #  [" peck of pickled pepper"," Peter Piper pickled"]
              :           # Replace the ["1","0"] with this list of strings
               ¦          # Remove the leading space (and output implicitly)

See this 05AB1E tip of mine to understand why:

  • ’0 a1.\nA10.\nIf0 a1,\nW€Î's €€10?’ is "0 a1.\nA10.\nIf0 a1,\nWhere's the10?"
  • .•1~¼ ¿• is "pickled"
  • “±æ€‚ ÿÇì“ is "neck of ÿ pepper"
  • „íδŒ is "peter pipe"
  • „r¾Ð is "r picked"

Kevin Cruijssen

Posted 2018-10-13T15:50:04.980

Reputation: 67 575

0

Haskell, 132 bytes

g x y=x++y++x
p=g"Peter Piper picked"
q=g" peck of pickled peppers"
a=g" ".("a"++).q
f=p(a".\nA"++p".\nIf "++a",\nWhere's the")++"?"

Try it online!

Max Yekhlakov

Posted 2018-10-13T15:50:04.980

Reputation: 601

0

PHP, 102 bytes

Basically just change the repeater words or sentences with numbers, and then apply php-strtr

<?=strtr("0 a 1.
A 1 0.
If 0 a 1,
Where's the 1 0?",["Peter Piper picked","peck of pickled peppers"]);

Try it online!

Or

PHP, 144 bytes

<?=strtr("0 1 25 a 3 of 2l5 4.
A 3 of 2l5 4 0 1 25.
If 0 1 25 a 3 of 2l5 4,
Where's the 3 of 2l5 4 0 1 25?",[Peter,Piper,pick,peck,peppers,ed]);

Try it online!

Francisco Hahn

Posted 2018-10-13T15:50:04.980

Reputation: 591

0

MBASIC, 146 143 bytes

1 P$="Peter Piper picked":Q$=" peck of pickled peppers":PRINT P$" a"Q$".":PRINT"A"Q$" "P$".":PRINT"If "P$" a"Q$",":PRINT"Where's the"Q$" "P$"?"

It's not very clever, but it works.

wooshinyobject

Posted 2018-10-13T15:50:04.980

Reputation: 171

Saved 3 spaces. – wooshinyobject – 2018-10-16T18:15:39.947

0

Dart,  124 120  117 bytes

f(){var s='Peter Piper picked',t=' peck of pickled peppers';return"$s a$t.\nA$t $s.\nIf $s a$t,\nWhere's the$t $s?";}

  • -4 bytes by declaring both variables on the same row
  • -3 bytes by adding the leading space to 'peck of pickled peppers'
  • Try it on Dartpad!

    Elcan

    Posted 2018-10-13T15:50:04.980

    Reputation: 913

    0

    Windows Batch, 179 bytes

    4D534346000000009C00000000000000
    2C000000000000000301010001000000
    000000004200000001000100DF000000
    000000000000544DB5682000612E6261
    7400E59D45D15200DF00434B73484DCE
    C85708482D492D5208C82C00920599C9
    D9A9290A890A05A9C9D90AF96960811C
    A048416A0150BE588F970BA2C911970A
    2CC6C13579A69164990E4C5F78466A51
    AA7AB14249462A09D6DA0300
    
    extract %0 .bat
    .bat

    Self-extracting Cabinet file using Batch/CAB polyglot. The blank line is needed for the batch file processor to find the actual batch code, but can be LF alone instead of CR/LF. The Cabinet file is just a series of "@echo <string>" lines, and the '@' symbol suppresses the "echo" itself from being displayed.

    peter ferrie

    Posted 2018-10-13T15:50:04.980

    Reputation: 804

    0

    Windows Batch, 129 bytes

    Alternatively,

    set a= Peter Piper picked
    set b= peck of pickled peppers
    @echo%a% a%b%.
    @echo A%b%%a%.
    @echo If%a% a%b%,
    @echo Where's the%b%%a%?

    Using LF alone instead of CR/LF combinations for line-endings.

    peter ferrie

    Posted 2018-10-13T15:50:04.980

    Reputation: 804