15
\$\begingroup\$

Your task is to, as the title discreetly suggests, make a bad fade animation of one word turning into a second word for yours truly.

What exactly is this "fade animation" you may ask?

To make a spectacular(ly bad) fade animation, you take two strings which will contain only printable ASCII characters. You start by printing your starting string (the first of the two). Then, you randomly pick a character in the original word and change it to the corresponding character in the word you want to animate to. When the words are of unequal length, you must pad them with spaces.

You keep on doing this until all of the characters have been changed, but you will not change the character at a certain index more than once. Here is an example i/o:

Hey -> Peeps
Hey    # original string
Hey s  # replace char at index 4
Hey s  # replace char at index 1
Pey s  # replace char at index 0
Pee s  # replace char at index 2
Peeps  # replace char at index 3

You must write a function or full program that changes a letter and then prints the new string at increments of one second. The input format is loose, but the output format is strict.

This is , so shortest code in bytes wins.

Some test cases (Form: init -> final):

Stringy -> Blingy
Banana -> Republic
United -> States
Make America -> Tissue box
I like walls -> I have small hands
Hello, -> world!

Reference implementation in Python 2:

import random
import time
def F(c,f):
    print c                                      # before we do stuff
    if len(c)>len(f):f+=" "*(len(c)-len(f))      # add padding part 1
    if len(f)>len(c):c+=" "*(len(f)-len(c))      # add padding part 2
    c, f = list(c), list(f)
    ai = [i for i in range(len(c))]              # a list for keeping track 
    while len(ai) > 0:                           #  of available indices
        time.sleep(1)                            # 1 second pause...
        i = ai.pop(random.randint(0,len(ai)-1))  # get a random index and remove
        c[i] = f[i]                              #   it from the list
        print ''.join(c)                         # print the new string
\$\endgroup\$
  • 7
    \$\begingroup\$ Stinking infinite loops are forbidden by default. Nice-smelling ones, too. \$\endgroup\$ – Martin Ender Sep 11 '16 at 17:05
  • \$\begingroup\$ I don't think the python code is valid? Because you have uncommented comments? \$\endgroup\$ – Conor O'Brien Sep 11 '16 at 17:19
  • \$\begingroup\$ Any restriction on the string length? \$\endgroup\$ – Titus Sep 11 '16 at 17:23
  • \$\begingroup\$ @ConorO'Brien, oh yeah.... oops :p \$\endgroup\$ – Daniel Sep 11 '16 at 17:23
  • \$\begingroup\$ @Titus, anything your language can handle I guess \$\endgroup\$ – Daniel Sep 11 '16 at 17:24

12 Answers 12

6
\$\begingroup\$

Pyth - 25 24 bytes

Will refactor.

AC.tQdV.SU
G
=XGN@HN.d_1

Try it online here.

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Ok, thanks for clarifying! \$\endgroup\$ – Luis Mendo Sep 11 '16 at 23:10
5
\$\begingroup\$

MATL, 33 bytes

cn2/XKZ@!Oyhg*XR"GcK:@mK:Eq+)D1Y.

Try it at MATL Online. You may need to refresh the page and press "Run" again if it doesn't work.

Alternatively, this version (35 bytes) deletes the screen before each new string is displayed, which results in the output being "modified in place":

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Does this have the one second pauses? It doesn't run on my phone. \$\endgroup\$ – Daniel Sep 11 '16 at 23:07
  • \$\begingroup\$ @Dopapp Yes, the final 1Y. is the pause within the loop. It works for me from my computer using Chrome \$\endgroup\$ – Luis Mendo Sep 11 '16 at 23:13
  • \$\begingroup\$ @Dopapp What operating system are you using? \$\endgroup\$ – Suever Sep 11 '16 at 23:58
  • \$\begingroup\$ @Suever, iOS 9. \$\endgroup\$ – Daniel Sep 12 '16 at 0:00
  • 1
    \$\begingroup\$ @Dopapp we're still working out some of the issues so let us know if you have any more. \$\endgroup\$ – Suever Sep 12 '16 at 0:26
2
\$\begingroup\$

Perl, 131 + 4 (-F -l) = 135 bytes

@T=@F if!$i++}$T[$_]||=$",$F[$_]||=$"for 0..$#F,0..$#T;say@T;{$==rand@T;redo if$h{$=}++;$T[$=]=$F[$=];sleep 1;say@T;redo if++$v!=@T

Needs -F and -l flags to run, as well as -M5.010 (or -E). Note that if your version of perl is a bit old, you'll need to add -an on your command line (which I'll add too bellow to show it, but it's not needed). For instance :

$ cat fade.pl
@T=@F if!$i++}$T[$_]||=$",$F[$_]||=$"for 0..$#F,0..$#T;say@T;{$==rand@T;redo if$h{$=}++;$T[$=]=$F[$=];sleep 1;say@T;redo if++$v!=@T
$ perl -F -anl -M5.010 fade.pl <<< "Hey
Peeps"
Hey  
Pey  
Pee  
Pee s
Pee s
Peeps

I'm pretty sure this could be shorter, but I couldn't find out how... yet! Still, I don't think this is a bad answer, and hopefully someone will be inspired to make it shorter (or have a totally different idea!).

|improve this answer|||||
\$\endgroup\$
2
\$\begingroup\$

Python 2, 171 169 168 163 bytes

import time,random as r
def f(a,b):
 d=len(a)-len(b);a+=' '*-d;b+=' '*d;o=range(len(a));r.shuffle(o);print a
 for i in o:time.sleep(1);a=a[:i]+b[i]+a[i+1:];print a

Test cases are on ideone

|improve this answer|||||
\$\endgroup\$
2
\$\begingroup\$

C# 299 Bytes

void f(string a,string b){var m=Math.Max(a.Length,b.Length);var t=new Collections.Generic.HashSet<int>();while(t.Count<m)t.Add(new Random().Next()%m);var s=a.PadRight(m).ToCharArray();Console.WriteLine(s);foreach(var x in t){Threading.Thread.Sleep(1000);s[x]=b.PadRight(m)[x];Console.WriteLine(s);}}

Ungolfed

void f(string a, string b)
{
    var m = Math.Max(a.Length, b.Length);
    var t = new Collections.Generic.HashSet<int>();
    while(t.Count < m) t.Add(new Random().Next()%m);
    var s=a.PadRight(m).ToCharArray();

    Console.WriteLine(s);
    foreach (var x in t)
    {
        Threading.Thread.Sleep(1000);
        s[x] = b.PadRight(m)[x];
        Console.WriteLine(s);
    }
}
|improve this answer|||||
\$\endgroup\$
2
\$\begingroup\$

Perl, 109 108 99 bytes

Includes +3 for -n

Give strings on STDIN without final newline

echo -n "Make -> Tissue box" | perl -M5.010 fade.pl

fade.pl:

#!/usr/bin/perl -n
/ -> /;$_=$`^$`^$'^$';{$==rand(y/\x00//)+sleep say+($`&~$_|$'&$_)=~y/\x00/ /r;s%(.*?\K\x00){$=}%\xff%&&redo}

Works as shown, but replace \xhh by the literal characters to get the claimed score.

This way of using \K is new I think...

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Awsome, as always! Took me a while to figure out how this works! Nice use of \K indeed. Note that there are two \0 in your code as well as \xff that can be replace by the corresponding literal characters, so the bytes count is actually 108. Also, maybe you didn't see it, but the input format is free, so there probably is something sorter than ` -> ` as a separator. \$\endgroup\$ – Dada Sep 27 '16 at 13:54
  • \$\begingroup\$ @Dada Ah right. Thanks. While developing I never use the literal characters, so it's easy to miss things when adjusting the byte count. Another separator can indeed gain up to 3 bytes, but it's an uninteresting change, so I'll just leave it \$\endgroup\$ – Ton Hospel Sep 27 '16 at 14:06
  • \$\begingroup\$ Yea of course. I don't recount all your solutions, but only when I experiment on them, and in that case it made me see those 4 bytes that you shouldn't have counted ;) \$\endgroup\$ – Dada Sep 27 '16 at 14:18
1
\$\begingroup\$

Python 3, 214 bytes

import time,random
o,f=list(input()),list(input())
F=len(f);O=len(o);o+=[" "]*(F-O);f+=[" "]*(O-F);p=-1;l=[p]
while o!=f:
 while p in l:p=random.randrange(max(F,O))
 l+=[p];o[p]=f[p];print(''.join(o));time.sleep(1)

Ideone it!

|improve this answer|||||
\$\endgroup\$
0
\$\begingroup\$

Java, 456 454 437 428 bytes

import java.util.*;public class c{public static void main(String[]s)throws Exception{char[]a=s[0].toCharArray(),b=s[1].toCharArray();int l,j=0;if(a.length<b.length){l=b.length;a=Arrays.copyOf(a,l);}else{l=a.length;b=Arrays.copyOf(b,l);}Vector i=new Vector();for(;j<l;i.add(j++));System.out.println(s[0]);while(l>0){Thread.sleep(1000);j=(int)i.remove(new Random().nextInt(l--));a[j]=b[j];System.out.println(String.valueOf(a));}}}

Ungolfed:

import java.util.*;

public class c
{

public static void main(String[] s) throws Exception
{
    char[] a = s[0].toCharArray(), b = s[1].toCharArray();
    int l, j = 0;
    if (a.length < b.length)
    {
        l = b.length;
        a = Arrays.copyOf(a, l);
    }
    else
    {
        l = a.length;
        b = Arrays.copyOf(b, l);
    }

    Vector i = new Vector();

    for (; j < l; i.add(j++));

    System.out.println(s[0]);

    while (l > 0)
    {
        Thread.sleep(1000);
        j = (int) i.remove(new Random().nextInt(l--));
        a[j] = b[j];
        System.out.println(String.valueOf(a));
    }
}
}

Edit: minus 2 byte by CAD97

Edit: minus 17 byte by Kevin Cruijssen (I slightly altered the suggestion by reusing j instead of creating a new variable x to hold the size)

Edit: minus 9 byte

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ You have unnecessary whitespace in your two Arrays::copyOf calls \$\endgroup\$ – CAD97 Sep 12 '16 at 5:25
  • \$\begingroup\$ As @CAD97 said, you can remove some unnecessary whitespaces; also at the arrays: String[]s and char[]a. Also, you can golf your first for-loop: for(;j<l;i.add(j++);; You can remove Random r=new Random(); and use it directly: new Random().nextInt(i.size()); You can also add ,x to the list of ints, and chance the while-loop to while((x=i.size())>0){...j=(int)i.remove(new Random().nextInt(x));...} And there is probably more to golf that I'm missing. \$\endgroup\$ – Kevin Cruijssen Sep 12 '16 at 7:10
0
\$\begingroup\$

PHP, 123 121 bytes

<?=$a=$argv[1];for($b=str_split(str_pad($argv[2],strlen($a)));$b;print"
$a"){$a[$i=array_rand($b)]=$b[$i];unset($b[$i]);}

save as file, execute with php <filename> <string1> <string2> (or php-cgi)

breakdown

<?=$a=$argv[1];                         // 0. print original
for(
    $b=str_split(                       // 2. split to array of single characers
        str_pad($argv[2],strlen($a))    // 1. pad 2nd argument to length of 1st argument
    );
    $b;                                 // 3. while $b has characters left
    print"\n$a"                         // 6. print altered string
){
    $a[$i=array_rand($b)]=$b[$i];       // 4. pick random index from $b, copy character to $a
    unset($b[$i]);                      // 5. remove character from $b
}
|improve this answer|||||
\$\endgroup\$
0
\$\begingroup\$

CJam, 44 bytes

q~{_,@\Se]s}2*1$peemr{es{_es-zA3#<}g;~t_p}/;

Explanation:

q~                                            get input
  {_,@\Se]s}2*                                pad each string to the length of the other
              1$p                             print starting string
                 eemr{                   }/   for each randomly shuffled enum of target string
                      es{_es-zA3#<}g;         1 second waiting loop    
                                     ~t_p     replace one character and print new string
                                           ;  clear stack

The delay only works using the Java interpreter, not in the online interpreter.

 java -jar cjam.jar badfade.cjam <<< '"banana" "republic"'

Try it online (delay set to 1 ms)

|improve this answer|||||
\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES6) + HTML, 210 bytes

s=>e=>{s=[...s],e=[...e],d=e[k="length"]-s[k],(d>0?s:e).push(..." ".repeat(d>0?d:-d)),a=[...e.keys()],u=_=>{O.value=s.join``,s[i=a.splice(Math.random()*a[k]|0,1)[0]]=e[i],i+1&&setTimeout(u,1e3)},u()}
<input id=O

Called using curry syntax: f("from this")("to this").

Cleaned up JS

s => e => {
    s = [...s],
    e = [...e],
    d = e[ k="length" ] - s[k],
    (d>0 ? s : e).push(..." ".repeat(d>0 ? d : -d)),
    a = [...e.keys()],
    u = _ => {
        O.value = s.join``,
        s[ i = a.splice(Math.random()*a[k]|0, 1)[0] ] = e[i],
        i+1 && setTimeout(u, 1e3)
    },
    u()
}

Test Snippet

Requires closing brace on the input to work here.

f=
s=>e=>{s=[...s],e=[...e],d=e[k="length"]-s[k],(d>0?s:e).push(..." ".repeat(d>0?d:-d)),a=[...e.keys()],u=_=>{O.value=s.join``,s[i=a.splice(Math.random()*a[k]|0,1)[0]]=e[i],i+1&&setTimeout(u,1e3)},u()}
<style>*{font-family:Consolas;}</style>
Starting String: <input id="A" type="text"><br>&nbsp;
Ending String: <input id="B" type="text">
<button onclick="f(A.value)(B.value)">Run</button>
<br><br>

<input id=O>

|improve this answer|||||
\$\endgroup\$
-1
\$\begingroup\$

Ruby, 106 bytes

->a,b{puts a=a.ljust(l=[a.size,b.size].max);b=b.ljust l
[*0...l].shuffle.map{|i|sleep 1;a[i]=b[i];puts a}}

Try it online!

Oh, all right. No more rick rolling in the Try It Online link, if that's what's causing the downvotes. If not, please let me know what I'm doing wrong

|improve this answer|||||
\$\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.