62
\$\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\$
  • 130
    \$\begingroup\$ Why was Vista afraid of 7? Because 7 8 10. \$\endgroup\$ – lirtosiast Dec 14 '15 at 18:12
  • 2
    \$\begingroup\$ Another test case 68978966897896 => 68977 \$\endgroup\$ – Brad Gilbert b2gills Dec 14 '15 at 18:29
  • 19
    \$\begingroup\$ @ThomasKwa Oh, I get it: Microsoft skipped Windows 9 because they were going along with the riddle. ;) \$\endgroup\$ – ETHproductions Dec 14 '15 at 19:18
  • 43
    \$\begingroup\$ Why afraid of seven was five? Because six seven eight. --Yoda \$\endgroup\$ – Jakuje Dec 14 '15 at 22:05
  • 2
    \$\begingroup\$ Six was afraid seven because seven had cold, dead eyes. \$\endgroup\$ – Conor O'Brien Jan 15 '16 at 20:07

28 Answers 28

33
\$\begingroup\$

Retina, 12

Translation of the sed answer:

6*7(6|89)*
7

Try it online

\$\endgroup\$
  • \$\begingroup\$ Works in QuadR too! \$\endgroup\$ – Adám Jun 27 '17 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\$
  • 12
    \$\begingroup\$ Great, and since 9 is eaten, you only have 2 bytes and win with this answer :P \$\endgroup\$ – Pierre Arlaud Dec 15 '15 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\$
  • 2
    \$\begingroup\$ Why not go with a lambda? Will save at least 15 bytes \$\endgroup\$ – GamrCorps Dec 15 '15 at 0:11
  • \$\begingroup\$ @GamrCorps Don't know how to phrase that - never use functions. \$\endgroup\$ – Addison Crump Dec 15 '15 at 6:47
  • 1
    \$\begingroup\$ what's the point of interface and not class? \$\endgroup\$ – eis Dec 15 '15 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\$ – Addison Crump Dec 15 '15 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\$ – Addison Crump Dec 16 '15 at 16:18
9
\$\begingroup\$

GNU Sed, 17

Score includes +1 for -r option.

s/6*7(6|89)*/7/g
\$\endgroup\$
  • \$\begingroup\$ Doesn't work for 67789 should return 77 but it instead returns 677 \$\endgroup\$ – Brad Gilbert b2gills Dec 14 '15 at 19:02
  • 1
    \$\begingroup\$ You can use s/67|7(6|89)/7/ instead of s/6?7(6|89)/7/ \$\endgroup\$ – Brad Gilbert b2gills Dec 14 '15 at 19:09
  • 1
    \$\begingroup\$ Gee, I wonder where Larry came up with the idea of s///g? \$\endgroup\$ – Brad Gilbert b2gills Dec 14 '15 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\$
  • \$\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\$ – Digital Trauma Dec 14 '15 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\$ – Brad Gilbert b2gills Dec 14 '15 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\$ – Brad Gilbert b2gills Dec 14 '15 at 21:04
  • 1
    \$\begingroup\$ Shouldn't the [] be changed to ()? You don't want to match pipes or 79999. \$\endgroup\$ – jwodder Dec 14 '15 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\$ – Brad Gilbert b2gills Dec 14 '15 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\$
4
\$\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\$
  • 8
    \$\begingroup\$ The golfed code is clearer than the explanation code.. :) \$\endgroup\$ – Rob Dec 14 '15 at 22:26
  • \$\begingroup\$ @Rob Haven't made many explanations before, going for a systematic approach. \$\endgroup\$ – LegionMammal978 Dec 15 '15 at 11:39
  • \$\begingroup\$ I was just teasing, mate :) \$\endgroup\$ – Rob Dec 15 '15 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\$
  • \$\begingroup\$ At least it's not Java \$\endgroup\$ – user45510 Dec 17 '15 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\$
  • \$\begingroup\$ You can use chars instead of size.times to save a few bytes. \$\endgroup\$ – Doorknob Dec 14 '15 at 21:51
  • \$\begingroup\$ Doesn't Ruby have the global flag for regex substitution, or would that take more bytes to enable? \$\endgroup\$ – Brad Gilbert b2gills Dec 14 '15 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 Dec 15 '15 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\$ – Brad Gilbert b2gills Dec 15 '15 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\$ – Alexis Andersen Dec 15 '15 at 15:40
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\$
2
\$\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\$
  • \$\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\$ – Peter Taylor Dec 16 '15 at 19:34
  • \$\begingroup\$ Thank you! I couldn't quite understand how to use your second suggestion however. \$\endgroup\$ – Conrad Crates Dec 16 '15 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\$ – Peter Taylor Dec 16 '15 at 19:49
2
\$\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\$
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\$

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\$
  • \$\begingroup\$ I don't think so. If you have a way to STDOUT, you have to. Sorry! \$\endgroup\$ – user45510 Dec 17 '15 at 2:48
  • \$\begingroup\$ Yes, this is allowed according to the meta post. \$\endgroup\$ – geokavel Dec 19 '15 at 15:12
1
\$\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\$
  • \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ – Mego Dec 16 '15 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 Dec 21 '15 at 4:44
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\$
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\$

PHP, 36 bytes

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

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

\$\endgroup\$
  • \$\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\$ – Mego Dec 15 '15 at 23:38
  • \$\begingroup\$ @Mego There appears to be no consensus on the post you linked to. \$\endgroup\$ – user253751 Dec 16 '15 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\$ – Mego Dec 16 '15 at 20:10
  • \$\begingroup\$ TL;DR you have serious disadvantages if you use PHP for codegolf. \$\endgroup\$ – HamZa Dec 17 '15 at 10:02
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\$

///, 19 bytes (non-competing)

/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.

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

Python 3, 46 bytes

import re
lambda s:re.sub(r'6*7(6|89)*','7',s)
\$\endgroup\$
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\$

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\$
0
\$\begingroup\$

05AB1E, 12 bytes

Δ67‚7:789¬:

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); which pushes 76 to the stack
    ‚           #  Pair them up
     7:         #  Replace all occurrences of 67 or 76 with 7 in the (implicit) input
                #   i.e. 17893762 → 1789372
       789      #  Push 789 to the stack
          ¬     #  Take the head (without popping); which pushes 7 to the stack
           :    #  Replace all 789 with 7
                #   i.e. 1789372 → 17372
                # (And implicitly output the result after the loop)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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