9
\$\begingroup\$

Inspired by the C-directive #define.

Challenge

Given one phrase with some alias, and one array with each alias text. Output the initial phrase replacing each alias with its respective text.

An alias is defined by one sharp # followed by its index in the array (the index may start at zero or one). Alias can contains another alias inside its text, and you must resolve all them (maybe recursively). You can assume the alias will never run into an infinite-loop. Alias won't have leading zeroes (#02 is not alias at index 2, it is alias at index 0 followed by the text 2).

You can assume the array will not pass 20 items in length.

You can write a program, or a function or even a #define-it would be nice :)

You can also use another input-method that fits better for your language.

Example

phrase: "#0 & #3"
array: [
    "Programming #1",
    "Puzzles",
    "Code",
    "#2 Golf"
]
output: "Programming Puzzles & Code Golf"

Step by step:

0> "#0 & #3"
1> "Programming #1 & #2 Golf"
2> "Programming Puzzles & Code Golf"

Since this is , shortest answer in bytes wins!

Another samples

phrase: "#0!"
array: [
    "We are #1",
    "#2",
    "#3",
    "#4 !",
    "graduating"
]
output: "We are graduating !!"

phrase: "##0#1#0#21#3#4"
array: [
    "a",
    "m",
    "z",
    "n",
    "g"
]
output: "#amaz1ng"

phrase: "##1#23"
array: [
    "WEIRD",
    "0 C",
    "AS"
]
output: "WEIRD CAS3"

phrase: "#1#7#6y#4#7#10s#7b#11#0#0#11r#7#0h#6#5#2#5#9#4."
array: [
    "t",
    "#12#3",
    "#11ga#3",
    "#0#10v#11",
    "#0h#10#8g",
    "#7#8",
    "a#8",
    " ",
    "n",
    "o",
    "i",
    "e",
    "P#9s#10"
]
output: "Positive anything is better than negative nothing."

The examples above used Array with index starting at zero.

\$\endgroup\$
  • \$\begingroup\$ If we use the 1-indexing option, do we not have to worry about the leading 0 thing becase #0 shouldn't appear? Or is #01 valid but not an alias (i.e. it just gets left in as is)? \$\endgroup\$ – FryAmTheEggman Mar 17 '16 at 13:58
  • \$\begingroup\$ @FryAmTheEggman. In that case you should just ignore #01 \$\endgroup\$ – removed Mar 17 '16 at 14:03
  • \$\begingroup\$ Easy with python for 0-9, mind blown trying to minimize 0-19 :D \$\endgroup\$ – Antti Haapala Mar 17 '16 at 16:39
  • 1
    \$\begingroup\$ There is a surprising amount of complexity hidden in what seems to be a simple problem. Great question! \$\endgroup\$ – Josh Mar 17 '16 at 17:06
4
\$\begingroup\$

JavaScript (ES6) 58

Recursive function

f=(s,h,r=s.replace(/#(1?\d)/g,(_,x)=>h[x]))=>r==s?r:f(r,h)

Test

f=(s,h,r=s.replace(/#(1?\d)/g,(_,x)=>h[x]))=>r==s?r:f(r,h)

// Version without default parameters, same length but using a global
// f=(s,h)=>(r=s.replace(/#(1?\d)/g,(_,x)=>h[x]))==s?r:f(r,h)

console.log=x=>O.textContent+=x+'\n'

;[
  ['##1#23',['WEIRD','0 C','AS']],
  ["#0!",["We are #1","#2","#3","#4 !","graduating"]],
  ["##0#1#0#21#3#4",["a","m","z","n","g"]],
  ["##0#1#0#21#13#4",["a","m","z","","g","","","","","","","","","n"]],
  ["#1#7#6y#4#7#10s#7b#11#0#0#11r#7#0h#6#5#2#5#9#4.",
    ["t","#12#3","#11ga#3","#0#10v#11","#0h#10#8g","#7#8","a#8"," ","n","o","i","e","P#9s#10"]
  ],
  ["#0 & #3",["Programming #1","Puzzles","Code","#2 Golf"]]
].forEach(t=>{
  var a=t[0],b=t[1]
  console.log(a+' ['+b+']\n -> '+f(a,b))
})
<pre id=O></pre>

\$\endgroup\$
  • \$\begingroup\$ I've added another test case with alias' index greater than 9. \$\endgroup\$ – removed Mar 17 '16 at 14:43
2
\$\begingroup\$

Mathematica, 74 bytes

FixedPoint[#~StringReplace~a&,a=0;a=Reverse["#"<>ToString@a++->#&/@#2];#]&

Not too complicated. Most of it is just dedicated to creating the indices.

\$\endgroup\$
  • 1
    \$\begingroup\$ @WashingtonGuedes Fixed. \$\endgroup\$ – LegionMammal978 Mar 17 '16 at 21:02
2
\$\begingroup\$

Julia, 112 107 66 bytes

f(s,x)=(r=replace(s,r"#1?\d",m->x[1+parse(m[2:end])]))==s?s:f(r,x)

This is a recursive function that accepts a string an an array and returns a string. It uses 0-based indexing.

We begin by constructing a string r as the input string s with all matches of the regular expression #1?\d replaced with the element of x corresponding to 1 + the integer parsed out of the match. If this is equal to s, we return s, otherwise we recurse, passing r as the string.

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

C, 269 232

#define f(p,a,l)char*n,o[999],i=0,c,x;for(strcpy(o,p);o[i];)o[i]==35&isdigit(o[i+1])?c=o[i+1]-48,c=isdigit(o[i+2])&c?10*c+o[i+2]-48:c,n=a[c<l?c:c/10],x=strlen(n),memmove(o+i+x,o+i+2+c/10,strlen(o+i)),i=!memmove(o+i,n,x):++i;puts(o);

As requested, a single #define solving the problem! C macros can't be recursive, so the problem had to be solved iteratively. The macro takes 3 arguments; the phrase p, the array a, and the length of the array l. I only stripped whitespace from my ungolfed solution; I know there are a few more characters I can save, but I don't think it will get me below 200. This will definitely not be a competitive solution. Solution is fully golfed. Ungolfed solution in the form of a function below:

f(char*p,char**a,int l){
  char o[999]={0},i=0;
  strcpy(o,p);
  while(o[i]){
    if(o[i]=='#'&&isdigit(o[i+1])){
      int c = o[i+1]-'0';
      if(isdigit(o[i+2])&&c)
        c=10*c+o[i+2]-'0';
      if(c>=l)
        c/=10;
      char *n=a[c];
      memmove(o+i+strlen(n),o+i+2+c/10,strlen(o+i));
      memmove(o+i,n,strlen(n));
      i=0;
    }else{
      i++;
    }
  }
  puts(o);
}

And test code:

void test(char *phrase, char **array, int length) {
  f(phrase, array, length);
}

main() {
  const char *t1[] = {
    "Programming #1","Puzzles","Code","#2 Golf"
  };
  test("#0 & #3", t1, 4);

  const char *t2[] = {
    "We are #1","#2","#3","#4 !","graduating"
  };
  test("#0!", t2, 5);

  const char *t3[] = {
    "a","m","z", "n","g"
  };
  test("##0#1#0#21#3#4", t3, 5);

  const char *t4[] = {
    "WEIRD","0 C","AS"
  };
  test("##1#23", t4, 3);

  const char *t5[] = {
    "t","#12#3","#11ga#3","#0#10v#11","#0h#10#8g","#7#8","a#8"," ","n","o","i","e","P#9s#10"
  };
  test("#1#7#6y#4#7#10s#7b#11#0#0#11r#7#0h#6#5#2#5#9#4.", t5, 13);
}

EDIT: Worked some golfing magic. It's as about as short and unreadable as I think it can get.

\$\endgroup\$
  • \$\begingroup\$ Man, nice one!!! ... I would upvote it again if I could ;) \$\endgroup\$ – removed Mar 17 '16 at 20:42

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.