Why was 6 afraid of 7?

62

6

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

geokavel

Posted 2015-12-14T18:06:45.110

Reputation: 6 352

130Why was Vista afraid of 7? Because 7 8 10. – lirtosiast – 2015-12-14T18:12:18.717

2Another test case 68978966897896 => 68977 – Brad Gilbert b2gills – 2015-12-14T18:29:16.280

19@ThomasKwa Oh, I get it: Microsoft skipped Windows 9 because they were going along with the riddle. ;) – ETHproductions – 2015-12-14T19:18:42.447

43

Why afraid of seven was five? Because six seven eight. --Yoda

– Jakuje – 2015-12-14T22:05:10.643

I could be wrong but I'm sure this is an example of a Lindenmayer system. – Pharap – 2015-12-17T12:12:16.473

@Pharap Link, please. – geokavel – 2015-12-17T15:40:38.350

@geokavel Facinating stuff. Here's three as a start: 1 2 3

– Pharap – 2015-12-17T15:57:29.330

@Pharap Thanks for the links! I guess the difference is mine always makes the string smaller, so maybe it's an inverse L-System? – geokavel – 2015-12-17T16:02:39.590

@geokavel Alphabet: 6789; Axiom: 78966; Rules: 67 -> 7, 789 -> 7; Not sure if that's entirely correct but you can see how it would be mapped to an L-system. – Pharap – 2015-12-17T16:14:01.263

@Pharap Nice. Also, 76 -> 7. – geokavel – 2015-12-17T16:16:04.213

@geokavel That too. If I knew of a language centred around L-Systems I'd submit an answer but I don't believe that there is one. – Pharap – 2015-12-17T16:18:15.593

2Six was afraid seven because seven had cold, dead eyes. – Conor O'Brien – 2016-01-15T20:07:56.903

Because of the "Keep applying these transformations until you can no longer.", it would be good to add some test cases reflecting that.. Like 68978966897896 that @BradGilbertb2gills suggested almost 3 years ago, or 76896897. – Kevin Cruijssen – 2018-09-06T08:14:33.050

Answers

33

Retina, 12

Translation of the sed answer:

6*7(6|89)*
7

Try it online

Digital Trauma

Posted 2015-12-14T18:06:45.110

Reputation: 64 644

Works in QuadR too!

– Adám – 2017-06-27T10:04:28.257

12

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;}
}

Addison Crump

Posted 2015-12-14T18:06:45.110

Reputation: 10 763

2Why not go with a lambda? Will save at least 15 bytes – GamrCorps – 2015-12-15T00:11:30.073

@GamrCorps Don't know how to phrase that - never use functions. – Addison Crump – 2015-12-15T06:47:43.743

1what's the point of interface and not class? – eis – 2015-12-15T19:42:04.983

3

@eis Interface removes the need to declare main as public, which gives the slightest advantage. See: http://codegolf.stackexchange.com/a/64713/44713

– Addison Crump – 2015-12-15T19:43:41.467

Lambda version: x->{for(;!x.equals((x=x.replaceAll("67|76|789","7"))););return x;} – GamrCorps – 2015-12-15T23:00:41.260

Forgot to add the new byte count (66) – GamrCorps – 2015-12-15T23:03:47.353

1@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. – Addison Crump – 2015-12-16T16:18:28.973

@FlagAsSpam i know, but seems it works when i test it – user902383 – 2015-12-16T16:22:28.577

@user902383 Huh. Must be an autoboxing thing I never saw before. I'll test it here as well. – Addison Crump – 2015-12-16T16:24:02.587

other thing is in your equal statement you have double bracket. equals(( statement )) – user902383 – 2015-12-16T16:26:43.797

@user902383 Yes, that was for the reassignment of x, but I forgot that single-functions statements don't need the extra brackets. – Addison Crump – 2015-12-16T16:32:26.170

12

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])

Qwertiy

Posted 2015-12-14T18:06:45.110

Reputation: 2 697

12Great, and since 9 is eaten, you only have 2 bytes and win with this answer :P – Pierre Arlaud – 2015-12-15T10:48:32.693

9

GNU Sed, 17

Score includes +1 for -r option.

s/6*7(6|89)*/7/g

Digital Trauma

Posted 2015-12-14T18:06:45.110

Reputation: 64 644

Doesn't work for 67789 should return 77 but it instead returns 677 – Brad Gilbert b2gills – 2015-12-14T19:02:32.027

1You can use s/67|7(6|89)/7/ instead of s/6?7(6|89)/7/ – Brad Gilbert b2gills – 2015-12-14T19:09:58.567

1Gee, I wonder where Larry came up with the idea of s///g? – Brad Gilbert b2gills – 2015-12-14T23:11:19.423

8

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

Brad Gilbert b2gills

Posted 2015-12-14T18:06:45.110

Reputation: 12 713

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? – Digital Trauma – 2015-12-14T19:10:46.907

2@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. – Brad Gilbert b2gills – 2015-12-14T19:14:01.153

1

@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

– Brad Gilbert b2gills – 2015-12-14T21:04:22.760

Cool - thanks for the explanation! No mean-spiritedness was given or taken :) My motivation is purely curiosity which your explanation has satisfied - thanks – Digital Trauma – 2015-12-14T21:28:55.043

1Shouldn't the [] be changed to ()? You don't want to match pipes or 79999. – jwodder – 2015-12-14T21:57:24.803

1@jwodder No [] is the Perl 6 non-capturing version of (), what you are thinking of is spelled as <[6|89]> in Perl 6. – Brad Gilbert b2gills – 2015-12-14T22:53:20.280

7

Pyth, 17 bytes

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

Try it here.

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

Mike Bufardeci

Posted 2015-12-14T18:06:45.110

Reputation: 1 680

4

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

Brad Gilbert b2gills

Posted 2015-12-14T18:06:45.110

Reputation: 12 713

4

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.

LegionMammal978

Posted 2015-12-14T18:06:45.110

Reputation: 15 731

8The golfed code is clearer than the explanation code.. :) – Rob – 2015-12-14T22:26:23.863

@Rob Haven't made many explanations before, going for a systematic approach. – LegionMammal978 – 2015-12-15T11:39:35.523

I was just teasing, mate :) – Rob – 2015-12-15T11:40:17.067

3

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}

MegaTom

Posted 2015-12-14T18:06:45.110

Reputation: 3 787

You can use chars instead of size.times to save a few bytes. – Doorknob – 2015-12-14T21:51:18.420

Doesn't Ruby have the global flag for regex substitution, or would that take more bytes to enable? – Brad Gilbert b2gills – 2015-12-14T23:14:44.797

@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. – manatwork – 2015-12-15T11:12:28.850

1@manatwork Then I would write this something like: ->s{s.gsub /6*7(6|89)*/,'7'}, and let gsub do all the looping work. – Brad Gilbert b2gills – 2015-12-15T15:20:53.980

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 – Alexis Andersen – 2015-12-15T15:40:55.493

@BradGilbertb2gills thank you for your help. – MegaTom – 2015-12-16T14:55:48.777

3

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
}

Doorknob

Posted 2015-12-14T18:06:45.110

Reputation: 68 138

At least it's not Java – None – 2015-12-17T02:49:41.507

3

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))

Lord Yuuma

Posted 2015-12-14T18:06:45.110

Reputation: 587

2

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.

Luis Mendo

Posted 2015-12-14T18:06:45.110

Reputation: 87 464

2

Japt, 15 bytes

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

Simple RegEx solution

Try it online

Downgoat

Posted 2015-12-14T18:06:45.110

Reputation: 27 116

2

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

TessellatingHeckler

Posted 2015-12-14T18:06:45.110

Reputation: 2 412

2

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

Conrad Crates

Posted 2015-12-14T18:06:45.110

Reputation: 21

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. – Peter Taylor – 2015-12-16T19:34:28.590

Thank you! I couldn't quite understand how to use your second suggestion however. – Conrad Crates – 2015-12-16T19:47:20.180

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. – Peter Taylor – 2015-12-16T19:49:18.173

1

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"

Mego

Posted 2015-12-14T18:06:45.110

Reputation: 32 998

1

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)

user253751

Posted 2015-12-14T18:06:45.110

Reputation: 818

I don't think so. If you have a way to STDOUT, you have to. Sorry! – None – 2015-12-17T02:48:50.133

Yes, this is allowed according to the meta post. – geokavel – 2015-12-19T15:12:03.443

1

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.

Pooping

Posted 2015-12-14T18:06:45.110

Reputation: 11

Welcome to PPCG! – Mego – 2015-12-16T23:57:40.610

@BinaryZebra Ah, thanks for the @() syntax. I knew there had to be a way to combine those. And @Mego, thanks for the welcome! – Pooping – 2015-12-21T04:44:10.017

1

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.

Mutador

Posted 2015-12-14T18:06:45.110

Reputation: 1 361

0

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

Bubbler

Posted 2015-12-14T18:06:45.110

Reputation: 16 616

0

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)

Kevin Cruijssen

Posted 2015-12-14T18:06:45.110

Reputation: 67 575

0

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

Conor O'Brien

Posted 2015-12-14T18:06:45.110

Reputation: 36 228

0

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.

Goose

Posted 2015-12-14T18:06:45.110

Reputation: 219

0

PHP, 36 bytes

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

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

daraeman

Posted 2015-12-14T18:06:45.110

Reputation: 11

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. – Mego – 2015-12-15T23:38:12.460

@Mego There appears to be no consensus on the post you linked to. – user253751 – 2015-12-16T09:28:48.527

@immibis Correct. A consensus is required to make an I/O method acceptable. The lack of one means it is not acceptable. – Mego – 2015-12-16T20:10:32.790

TL;DR you have serious disadvantages if you use PHP for codegolf. – HamZa – 2015-12-17T10:02:38.893

0

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))))

Bob Jarvis - Reinstate Monica

Posted 2015-12-14T18:06:45.110

Reputation: 544

0

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

Adám

Posted 2015-12-14T18:06:45.110

Reputation: 37 779

0

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

Erik the Outgolfer

Posted 2015-12-14T18:06:45.110

Reputation: 38 134

Note that Itflabtijtslwi is slashes but with input.

– FryAmTheEggman – 2016-06-03T15:58:37.100

@FryAmTheEggman Although that one inputs characters, not strings. – Erik the Outgolfer – 2016-06-03T18:37:02.113

Your link seems to be missing one slash. – Delioth – 2016-08-18T20:54:50.780

0

Python 3, 46 bytes

import re
lambda s:re.sub(r'6*7(6|89)*','7',s)

Justin

Posted 2015-12-14T18:06:45.110

Reputation: 417