66
\$\begingroup\$

Why was 6 afraid of 7? Because 7 8 9!

Given a string apply the following transformations:

  • If there is a 6 next to a 7 remove the 6 (6 is afraid of 7)
  • If the sequence "789" appears remove the 8 and the 9 (7 ate 9)

(If I'm not mistaken it doesn't matter what order you do the transformations in)

Keep applying these transformations until you can no longer.

Example:

78966

First we see "789", so the string becomes "766". Then we see "76", so we take out the 6, and the string becomes "76". Then we see "76" again, so we are left with "7".

Test Cases:

  • 987 => 987 (Not in the right order. Does nothing.)
  • 6 7 => 6 7 (The whitespace acts as a buffer between 6 and 7. Nothing happens)
  • 676 => 7
  • 7896789 => 77
  • 7689 => 7
  • abcd => abcd
\$\endgroup\$
15
  • 141
    \$\begingroup\$ Why was Vista afraid of 7? Because 7 8 10. \$\endgroup\$
    – lirtosiast
    Commented Dec 14, 2015 at 18:12
  • 2
    \$\begingroup\$ Another test case 68978966897896 => 68977 \$\endgroup\$ Commented Dec 14, 2015 at 18:29
  • 21
    \$\begingroup\$ @ThomasKwa Oh, I get it: Microsoft skipped Windows 9 because they were going along with the riddle. ;) \$\endgroup\$ Commented Dec 14, 2015 at 19:18
  • 45
    \$\begingroup\$ Why afraid of seven was five? Because six seven eight. --Yoda \$\endgroup\$
    – Jakuje
    Commented Dec 14, 2015 at 22:05
  • 3
    \$\begingroup\$ Six was afraid seven because seven had cold, dead eyes. \$\endgroup\$ Commented Jan 15, 2016 at 20:07

29 Answers 29

31
\$\begingroup\$

Retina, 12

Translation of the sed answer:

6*7(6|89)*
7

Try it online

\$\endgroup\$
1
  • \$\begingroup\$ Works in QuadR too! \$\endgroup\$
    – Adám
    Commented Jun 27, 2017 at 10:04
12
\$\begingroup\$

Javascript ES6, 29 bytes

s=>s.replace(/6*7(89|6)*/g,7)

Test:

f=s=>s.replace(/6*7(89|6)*/g,7)
;`987 -> 987
6 7 -> 6 7
676 -> 7
7896789 -> 77
7689 -> 7
abcd -> abcd`
.split`\n`.every(t=>(t=t.split` -> `)&&f(t[0])==t[1])
\$\endgroup\$
1
  • 12
    \$\begingroup\$ Great, and since 9 is eaten, you only have 2 bytes and win with this answer :P \$\endgroup\$ Commented Dec 15, 2015 at 10:48
12
\$\begingroup\$

Java, 126 81 66 58 bytes

Thanks to @GamrCorps for providing the lambda version of this code!

Thanks to @user902383 for pointing out an autoboxing trick!

...yup.

It's actually longer than I expected - Java replaces items in strings with replaceAll() once per match, not repeatedly until it stops changing. So I had to use a fancy for loop.

Lambda form:

x->{for(;x!=(x=x.replaceAll("67|76|789","7")););return x;}

Function form:

String s(String x){for(;x!=(x=x.replaceAll("67|76|789","7")););return x;}

Testable Ungolfed Code:

class B{
    public static void main(String[]a){
        System.out.print(new B().s(a[0]));
    }
    String s(String x){for(;x!=(x=x.replaceAll("67|76|789","7")););return x;}
}
\$\endgroup\$
11
  • 2
    \$\begingroup\$ Why not go with a lambda? Will save at least 15 bytes \$\endgroup\$
    – GamrCorps
    Commented Dec 15, 2015 at 0:11
  • \$\begingroup\$ @GamrCorps Don't know how to phrase that - never use functions. \$\endgroup\$ Commented Dec 15, 2015 at 6:47
  • 1
    \$\begingroup\$ what's the point of interface and not class? \$\endgroup\$
    – eis
    Commented Dec 15, 2015 at 19:42
  • 3
    \$\begingroup\$ @eis Interface removes the need to declare main as public, which gives the slightest advantage. See: codegolf.stackexchange.com/a/64713/44713 \$\endgroup\$ Commented Dec 15, 2015 at 19:43
  • 1
    \$\begingroup\$ @user902383 The reduction you're making is by changing .equals to !=, which does not do the same thing. == (or !=) compares by object hex location, not by value. It's the same length otherwise. while() is 7 bytes, for(;;) is 7 bytes. \$\endgroup\$ Commented Dec 16, 2015 at 16:18
9
\$\begingroup\$

GNU Sed, 17

Score includes +1 for -r option.

s/6*7(6|89)*/7/g
\$\endgroup\$
3
  • \$\begingroup\$ Doesn't work for 67789 should return 77 but it instead returns 677 \$\endgroup\$ Commented Dec 14, 2015 at 19:02
  • 1
    \$\begingroup\$ You can use s/67|7(6|89)/7/ instead of s/6?7(6|89)/7/ \$\endgroup\$ Commented Dec 14, 2015 at 19:09
  • 1
    \$\begingroup\$ Gee, I wonder where Larry came up with the idea of s///g? \$\endgroup\$ Commented Dec 14, 2015 at 23:11
8
\$\begingroup\$

Perl 6, 19  18 bytes

{S:g/6*7[6|89]*/7/} # 19 bytes

$ perl6 -pe 's:g/6*7[6|89]*/7/' # 17 + 1 = 18 bytes

( Note that [6|89] is the non-capturing version of (6|89) which is spelt as (?:6|89) in Perl 5. <[6|89]> is how you would write what's spelt as [6|89] in Perl 5)

usage:

$ perl6 -pe 's:g/6*7[6|89]*/7/' <<< '
987
6 7
6676689
7896789
7689
abcd
68978966897896
79|689
'
987
6 7
7
77
7
abcd
68977
79|689
\$\endgroup\$
6
  • \$\begingroup\$ I don't know Perl 6, but I assume this is a repeated substitution. If the 6* and the [6|89]* don't match anything, what stops the 7 being substituted for 7 ad infinitum? \$\endgroup\$ Commented Dec 14, 2015 at 19:10
  • 2
    \$\begingroup\$ @DigitalTrauma It swaps 7 with 7 then starts again at the next position, working its way until the end. :g is short for :global not repeat until it doesn't match anymore. \$\endgroup\$ Commented Dec 14, 2015 at 19:14
  • 1
    \$\begingroup\$ @DigitalTrauma To get s/67|76|789/7/ to work on 667 I would have to write it as something to the effect of: while s/67|76|789/7/ {} which of course would never stop if you wrote it as while s/6*7[6|89]*/7/ {} as you would expect. Also, the end of the previous comment may come off as mean spirited, that is not how it was inteded \$\endgroup\$ Commented Dec 14, 2015 at 21:04
  • 1
    \$\begingroup\$ Shouldn't the [] be changed to ()? You don't want to match pipes or 79999. \$\endgroup\$
    – jwodder
    Commented Dec 14, 2015 at 21:57
  • 1
    \$\begingroup\$ @jwodder No [] is the Perl 6 non-capturing version of (), what you are thinking of is spelled as <[6|89]> in Perl 6. \$\endgroup\$ Commented Dec 14, 2015 at 22:53
7
\$\begingroup\$

Pyth, 17 bytes

u:G"67|76|789"\7z

Try it here.

Leaky Nun has outgolfed this by a byte in the comments.

\$\endgroup\$
1
5
\$\begingroup\$

Perl 5, 17 bytes

perl -pe 's/6*7(6|89)*/7/g' # 16 + 1

usage:

$ perl -pe 's/6*7(6|89)*/7/g' <<< '
987
6 7
6676689
7896789
7689
abcd
68978966897896
'
987
6 7
7
77
7
abcd
68977
\$\endgroup\$
4
\$\begingroup\$

Mathematica, 52 bytes

StringReplace[#,"67"|"76"|"789"->"7"]&~FixedPoint~#&

Explanation:

                                                   &   A function returning
                                     &                   a function returning
              #                                            its first argument
StringReplace[ ,                    ]                     with
                "67"                                        "67"
                    |                                      or
                     "76"                                   "76"
                         |                                 or
                          "789"                             "789"
                               ->                         replaced with
                                 "7"                       "7"
                                    ~FixedPoint~        applied to
                                                #        its first argument
                                                        until it no longer changes.
\$\endgroup\$
3
  • 8
    \$\begingroup\$ The golfed code is clearer than the explanation code.. :) \$\endgroup\$
    – Rob
    Commented Dec 14, 2015 at 22:26
  • \$\begingroup\$ @Rob Haven't made many explanations before, going for a systematic approach. \$\endgroup\$ Commented Dec 15, 2015 at 11:39
  • \$\begingroup\$ I was just teasing, mate :) \$\endgroup\$
    – Rob
    Commented Dec 15, 2015 at 11:40
3
\$\begingroup\$

Rust, 96 bytes

fn f(mut s:String)->String{for _ in 0..s.len(){for r in&["67","76","789"]{s=s.replace(r,"7")}}s}

Hopelessly long, as per usual for Rust...

Ungolfed:

fn seven_ate_nine(mut str: String) -> String {
    for _ in 0..str.len() {
        for to_replace in &["67","76","789"] {
            str = str.replace(to_replace, "7");
        }
    }
    s
}
\$\endgroup\$
1
  • \$\begingroup\$ At least it's not Java \$\endgroup\$
    – user45510
    Commented Dec 17, 2015 at 2:49
3
\$\begingroup\$

Emacs Lisp, 59 bytes

(lambda(s)(replace-regexp-in-string"6*7\\(6\\|89\\)*""7"s))

It becomes a bit clearer with spaces:

(lambda (s) (replace-regexp-in-string "6*7\\(6\\|89\\)*" "7" s))
\$\endgroup\$
3
\$\begingroup\$

Ruby, 27 bytes

This solution is from comments, credit to Brad Gilbert b2gills.

->s{s.gsub /6*7(6|89)*/,?7}

Ruby, 37 bytes

(old solution)

This solution uses the fact that you will never need to replace more times than characters in the string.

->s{s.chars{s.sub! /67|76|789/,?7};s}
\$\endgroup\$
6
  • \$\begingroup\$ You can use chars instead of size.times to save a few bytes. \$\endgroup\$
    – Doorknob
    Commented Dec 14, 2015 at 21:51
  • \$\begingroup\$ Doesn't Ruby have the global flag for regex substitution, or would that take more bytes to enable? \$\endgroup\$ Commented Dec 14, 2015 at 23:14
  • \$\begingroup\$ @BradGilbertb2gills, in Ruby is like in Awk: there are separate sub() and gsub() methods to replace first or all. So global is just one character longer. \$\endgroup\$
    – manatwork
    Commented Dec 15, 2015 at 11:12
  • 1
    \$\begingroup\$ @manatwork Then I would write this something like: ->s{s.gsub /6*7(6|89)*/,'7'}, and let gsub do all the looping work. \$\endgroup\$ Commented Dec 15, 2015 at 15:20
  • \$\begingroup\$ If I understand the rules of command line flags correctly, you could save 16 bytes by using the -p command line flag (+1) making it gsub /6*7(6|89)*/,?7 with usage ruby -pe "gsub /6*7(6|89)*/,?7" for a total of 20+1 bytes \$\endgroup\$ Commented Dec 15, 2015 at 15:40
3
\$\begingroup\$

MATL, 17 bytes

jt"'789|76'55cYX]

Example

>> matl
 > jt"'789|76'55cYX]
 > 
> 7896789
77

EDIT: Try it online!

Explanation

j                   % input string
t                   % duplicate
"                   % for each character. Iterates as many times as the string length
    '789|76'        % regular expression for replacement
    55c             % string to insert instead: character '7'
    YX              % regexprep
]                   % end for

This works by applying a regular expresion replacement for as many times as there are characters in the original string. This is enough, since each substitution reduces the number of characters.

\$\endgroup\$
2
\$\begingroup\$

Japt, 15 bytes

Ur"6*7(89|6)*"7

Simple RegEx solution

Try it online

\$\endgroup\$
2
\$\begingroup\$

PowerShell, 27 bytes

$args-replace'6*7(89|6)*',7

e.g.
PS C:\temp> .\ate.ps1 "7689"
7

PS C:\temp> .\ate.ps1 "abcd"
abcd

PS C:\temp> .\ate.ps1 "68978966897896"
68977

Making use of:

  • someone else's regex pattern
  • the way -replace does a global replace by default in PowerShell
  • loop unrolling, where it will apply the -regex operator to the array $args by applying it to all the elements individually, and there's only one element here because there's only one script parameter, so it works OK and we can avoid having to index element [0].

Novelty previous attempt before realising a global replace would do it; 74 bytes of building a chain of "-replace -replace -replace" using string multiplication, as many times as the length of the string, then eval()ing it:

"'$($args)'"+("{0}6|6(?=7)'{0}89'"-f"-replace'(?<=7)")*$args[0].Length|iex

(With a bit of string substitution to shorten the number of replaces).

\$\endgroup\$
1
\$\begingroup\$

Seriously, 29 bytes

,;l`'7;;"67"(Æ"76"(Æ"789"(Æ`n

Takes input as a double-quoted string, like "6789". Try it online (you will need to manually quote the input).

Explanation:

,;l`'7;;"67"(Æ"76"(Æ"789"(Æ`n
,;l                            get input and push its length (we'll call it n)
   `                       `n  call the following function n times:
    '7;;"67"(Æ                   replace all occurrences of "67" with "7"
              "76"(Æ             replace all occurrences of "76" with "7"
                    "789"(Æ      replace all occurrences of "789" with "7"
\$\endgroup\$
1
\$\begingroup\$

PHP, 36 bytes

preg_replace('/6*7(6|89)*/','7',$a);

regex solution, takes $a string and replaces via the expression.

\$\endgroup\$
4
  • \$\begingroup\$ GET parameters are not acceptable as an input method in PHP. You will need to either make this a function and pass the input as function parameters, or get input from $argv or STDIN. \$\endgroup\$
    – user45941
    Commented Dec 15, 2015 at 23:38
  • \$\begingroup\$ @Mego There appears to be no consensus on the post you linked to. \$\endgroup\$
    – user20574
    Commented Dec 16, 2015 at 9:28
  • \$\begingroup\$ @immibis Correct. A consensus is required to make an I/O method acceptable. The lack of one means it is not acceptable. \$\endgroup\$
    – user45941
    Commented Dec 16, 2015 at 20:10
  • \$\begingroup\$ TL;DR you have serious disadvantages if you use PHP for codegolf. \$\endgroup\$
    – HamZa
    Commented Dec 17, 2015 at 10:02
1
\$\begingroup\$

Thue, 26 bytes

67::=7
76::=7
789::=7
::=

including a trailing newline.

Input is appended to the program before starting it.
Output is read off the program state when it terminates, similarly to a Turing machine.
(Thue does have an output stream, but it's difficult to use correctly, so I'm not sure whether this is an acceptable output method)

\$\endgroup\$
2
  • \$\begingroup\$ I don't think so. If you have a way to STDOUT, you have to. Sorry! \$\endgroup\$
    – user45510
    Commented Dec 17, 2015 at 2:48
  • \$\begingroup\$ Yes, this is allowed according to the meta post. \$\endgroup\$
    – geokavel
    Commented Dec 19, 2015 at 15:12
1
\$\begingroup\$

CJam, 70 64 bytes

Thanks to @Peter Taylor for cutting {"789":I}{"76:":I}? to "789""76"?:I

"67":Iq:A{AI#:B){AB<7+A{BI,+}~>+s:A];}{"76"I={"789":I}{"76":I}?];}?}/A

"67":Iq:A{AI#:B){AB<7+A{BI,+}~>+s:A];}{"76"I="789""76"?:I];}?}/A

I know this could probably be golfed a lot further and your help would be greatly appreciated, but frankly I'm just happy I managed to get the answer. This was my first attempt at writing CJam.

Explanation:

"67":I                e# Assign the value of 67 to I
q:A                   e# Read the input and assign to A
{                     e# Opening brackets for loop
    AI#:B)            e# Get the index of I inside A and assign to B. The increment value by 1 to use for if condition (do not want to process if the index was -1)
    {                 e# Open brackets for true result of if statement
        AB<           e# Slice A to get everything before index B
        7+            e# Append 7 to slice
        A{BI,+}~>     e# Slice A to get everything after index B plus the length of string I (this will remove I entirely)
        +s:A          e# Append both slices, convert to string, and assign back to A
        ];            e# Clear the stack
    }                 e# Closing brackets for the if condition
    {                 e# Open brackets for false result of if statement
        "76"I=        e# Check if I is equal to 76
        "789"         e# If I is 76, make I 789
        "76"?:I       e# If I is not 76, make I 76
        ];            e# Clear the stack if I does not exist inside A
    }?                e# Closing brackets for false result of if statement
}/                    e# Loop
A                     e# Output A
\$\endgroup\$
3
  • \$\begingroup\$ I haven't attempted this question myself, so I'm not sure whether this is the best approach, but if you want to do splitting and joining then take a look at / and *. Also note that thinking in terms of stacks when you're used to C-like languages takes some adaptation. E.g. {"789":I}{"76":I}? can pull out the assignment to become "789""76"?:I, which can be further golfed to 78976`3/?:I. \$\endgroup\$ Commented Dec 16, 2015 at 19:34
  • \$\begingroup\$ Thank you! I couldn't quite understand how to use your second suggestion however. \$\endgroup\$ Commented Dec 16, 2015 at 19:47
  • \$\begingroup\$ Sorry, my mistake. 78976`3/ gives an array ["789" "76"]; then rather than using ? you would need to use = to index; but it's back-to-front, so it would need the index to be inverted, losing the advantage. \$\endgroup\$ Commented Dec 16, 2015 at 19:49
1
\$\begingroup\$

R, 35 bytes

cat(gsub("6*7(6|89)*",7,scan(,"")))

I didn't know I could use gsub this way, a big thank you for every answer here that made me learn something new.

\$\endgroup\$
1
\$\begingroup\$

Python 3, 46 bytes

import re
lambda s:re.sub(r'6*7(6|89)*','7',s)
\$\endgroup\$
1
\$\begingroup\$

Dyalog APL, 17 bytes

'6*7(6|89)*'⎕R'7'

'6* any number of sixes
7 followed by a seven
()*' followed by zero or more sequences of…
6|89 a six or eight-nine

⎕RReplace that with

'7' a seven

\$\endgroup\$
1
\$\begingroup\$

///, 19 bytes

/67/7//76/7//789/7/

You can't actually provide input in this language, so the supposed input goes to the right of the code, which is allowed by recent rules.

\$\endgroup\$
3
  • \$\begingroup\$ Note that Itflabtijtslwi is slashes but with input. \$\endgroup\$ Commented Jun 3, 2016 at 15:58
  • \$\begingroup\$ @FryAmTheEggman Although that one inputs characters, not strings. \$\endgroup\$ Commented Jun 3, 2016 at 18:37
  • \$\begingroup\$ Your link seems to be missing one slash. \$\endgroup\$
    – Delioth
    Commented Aug 18, 2016 at 20:54
0
\$\begingroup\$

PHP 51 characters

while($s!=$r=str_replace([789,67,76],7,$s)){$s=$r;}

Test case written in long hand

$s = '78966';
while ($s != $r = str_replace([789, 67, 76], 7, $s) )
{
    $s = $r;
}
echo $s; // 7;

This does the string comparison and the string replace both in the while condition. If while condition is met, it updates the left hand of the comparison with the result. Let me know of any improvements.

\$\endgroup\$
0
\$\begingroup\$

Jolf, 15 bytes

Try it here! Do I really have to explain?

pi"6*7(6|89)*"7
p               replace any entity in
 i               the input
  "6*7(6|89)*"   that matches this regex
              7  with 7
                implicit output
\$\endgroup\$
0
\$\begingroup\$

Clojure, 71 bytes

Clojure is less-than-ideal for golfing due to its verbose nature - but nonetheless it's an interesting exercise:

Golfed version, using Java interop:

(defn f[s](let[x(.replaceAll s "67|76|789" "7")](if(= s x)s(recur x))))

Un-golfed version, using Java interop:

(defn six-fears-seven [s]
  (let [x (.replaceAll s "67|76|789" "7")]
    (if (= s x)
      s
      (recur x))))

Un-golfed "pure Clojure" version:

(defn six-fears-seven [s]
  (let [x (clojure.string/replace s #"67|76|789" "7")]
    (if (= s x)
      s
      (recur x))))
\$\endgroup\$
0
\$\begingroup\$

Bash, 102 82 67 (+7)? bytes

extglob version

x=$1
while v=${x/@(76|67|789)/7};[ $v != $x ];do x=$v;done
echo $v

This is meant to be put in a file and called with e.g. bash -O extglob 789.sh 6567678989689789656. The (+7)? bytes is for if the extglob option counts toward bytes.

Thanks to @BinaryZebra for pointing out extglob features!


Non-extglob version (82 bytes)

x=$1
while v=${x/76/7};v=${v/67/7};v=${v/789/7};[ $v != $x ];do x=$v;done
echo $v

This is meant to be put in a file and called with e.g. ./789.sh 65678989656.

It makes use of parameter expansion to search and replace in a loop. I involved a series of expansions to do the replacing since I'm not aware of a way to more effectively chain expansions.

\$\endgroup\$
2
  • \$\begingroup\$ Welcome to PPCG! \$\endgroup\$
    – user45941
    Commented Dec 16, 2015 at 23:57
  • \$\begingroup\$ @BinaryZebra Ah, thanks for the @() syntax. I knew there had to be a way to combine those. And @Mego, thanks for the welcome! \$\endgroup\$
    – Pooping
    Commented Dec 21, 2015 at 4:44
0
\$\begingroup\$

Japt v2.0a0, 12 bytes

e/6?7(6|89/7

Try it online!

How it works

String.e is recursive replace function. Japt 2 has a new regex syntax and auto-completion of parentheses inside regex, which saves one byte here. (In Japt 1.x, we had to pass strings in place of regexes, which was kinda clunky.)

\$\endgroup\$
0
\$\begingroup\$

05AB1E, 12 11 bytes

Δ67‚789ª7:

Try it online or verify all test cases.

Explanation:

Δ            # Continue doing the following until it no longer changes:
 67          #  Push 67 to the stack
   Â         #  Bifurcate (short for Duplicate & Reverse copy): 76
    ‚        #  Pair them together: [67,76]
     789ª    #  Append 789 to this list: [67,76,789]
         7:  #  Replace all occurrences of these three integers with 7
             #   i.e. 1789372 → 17372
             # (after the loop, output the result after implicitly)

67‚789ª could alternatively be •4BĆx•₄в for the same byte-count.

\$\endgroup\$
0
\$\begingroup\$

K (ngn/k), 27 bytes

{x{"7"/y@x}/(\'$67 76 789)}

Try it online!

  • $67 76 789 shorthand for ("67";"76";"789")
  • (\'...) create list of splitter functions, i.e. ("67"\;"76"\";"789"\)
  • x{...}/(...) set up a reduce, seeded with x (the input), run over the list of splitter functions
    • {"7"/y@x} split the input (x) using the current splitter function (y), then join the result with "7". feed this to the next iteration of the reduce
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.