[Question]
  [
I've recently been indulging myself in some nostalgia
in the form of Bookworm Deluxe:
![](https://i.stack.imgur.com/c1x3x.png)
In case you haven't seen it before,
it's a word game where the goal is to connect adjacent tiles to form words.
In order to determine whether a string is a valid word,
it checks it against its internal dictionary,
which is stored in a compressed format that looks like this:
```
aa
2h
3ed
ing
s
2l
3iis
s
2rdvark
8s
4wolf
7ves
```
The rules for unpacking the dictionary are simple:
1. Read the number at the start of the line,
and copy that many characters from the beginning of the previous word.
(If there is no number,
copy as many characters as you did last time.)
2. Append the following letters to the word.
So, our first word is `aa`,
followed by `2h`,
which means "copy the first two letters of `aa` and append `h`,"
forming `aah`.
Then `3ed` becomes `aahed`,
and since the next line doesn't have a number,
we copy 3 characters again to form `aahing`.
This process continues throughout the rest of the dictionary.
The resulting words from the small sample input are:
```
aa
aah
aahed
aahing
aahs
aal
aaliis
aals
aardvark
aardvarks
aardwolf
aardwolves
```
Your challenge is to perform this unpacking
in as few bytes as possible.
Each line of input will contain zero or more digits `0-9`
followed by one or more lowercase letters `a-z`.
You may take input and give output
as either a list of strings,
or as a single string with words separated by any character other than `0-9`/`a-z`.
Here is another small test case
with a few edge cases not covered in the example:
```
abc cba 1de fg hi 0jkl mno abcdefghijk 10l
=> abc cba cde cfg chi jkl mno abcdefghijk abcdefghijl
```
You may also test your code on the full dictionary:
[input](https://gist.githubusercontent.com/KeyboardFire/755e04d8d51c195c8688184bf3890588/raw/e7c236cb179acb1de859b5ed6b0569d7766bc911/input.txt),
[output](https://gist.githubusercontent.com/KeyboardFire/755e04d8d51c195c8688184bf3890588/raw/e7c236cb179acb1de859b5ed6b0569d7766bc911/output.txt).
  
[Answer]
# Vim, 57 bytes
```
:%s/\a/ &
:%norm +hkyiwjP
:g/\d/norm diw-@"yl+P
:%s/ //g
```
[Try it online!](https://tio.run/##HcpNCoAgFEbR@bcKCWoS8WrqqCW0ACea5m8JBUWrN2l67r1L4e1FQhLrwNsjnzvrXXz9ExZwS0LTb9o/w9y8qa9af0ZkUYpUK1YlMWmDzcJ5jCEm7EdGTdps1vkQMY3pAw "V – Try It Online")
[Answer]
# JavaScript (ES6), ~~66 62~~ 61 bytes
```
a=>a.map(p=s=>a=a.slice([,x,y]=/(\d*)(.*)/.exec(s),p=x||p)+y)
```
[Try it online!](https://tio.run/##ZY1NEoIwDEb3XoRWsfg3o5t6EWQR2xQKhXaogzjD3TFduHLzknzJvLQwQVSjDa/94DWuRq4g7yB6CCzISK0EEZ1VyMp8zj@VLNhDbzkTW14InFGxyPMg52UJfPfhq/JD9A6F8zUzrMwAsjw7NYQzaqIdamJMoUuhtfE3j3qCsaPulsbL2ztD9TphzCrON3/mp6K1eqYHR41Ek9SNJRzaLtn7wRPpUKOpG9sm@fHgkm79Ag "JavaScript (Node.js) – Try It Online")
### Commented
```
a =>                  // a[] = input, re-used to store the previous word
  a.map(p =           // initialize p to a non-numeric value
  s =>                // for each string s in a[]:
    a =               //   update a:
      a.slice(        //     extract the correct prefix from the previous word:
        [, x, y] =    //       load into x and y:
          /(\d*)(.*)/ //         the result of a regular expression which splits the new
          .exec(s),   //         entry into x = leading digits and y = trailing letters
                      //       this array is interpreted as 0 by slice()
        p = x || p    //       update p to x if x is not an empty string; otherwise leave
                      //       it unchanged; use this as the 2nd parameter of slice()
      )               //     end of slice()
      + y             //     append the new suffix
  )                   // end of map()
```
[Answer]
# [brainfuck](https://github.com/TryItOnline/brainfuck), 201 bytes
```
,[[[-<+>>>+<<]>-[---<+>]<[[-<]>>]<[-]>>[<<,>>>[-[-<++++++++++>]]++++<[->+<]-[----->-<]<]<]>>>[[>>]+[-<<]>>[[>>]+[<<]>>-]]+[>>]<[-]<[<<]>[->[>>]<+<[<<]>]>[>.>]+[>[-]<,.[->+>+<<]>>----------]<[<<]>-<<<,]
```
[Try it online!](https://tio.run/##PU7LDoMwDLv7VyCIx6TtUOVHqh7Ku8CYBBr7fJYAIj3Edm235eLD3H6rcd9jay2ZiJkjYxyTJVLqjMqOFZAsa0wsHktqvoed0yUWSbsjS8SS06N2KwWRRJRd5MAkQXuVm0OSikOITioCJ2pndcSJvnD@kOmeKyr1Jnb77j3yHkVTI8wdVuQTihBWRUu9@WXEa8Xj95laPLdmRerLClXpkdUN2g59QDqME97zB3JVN23Xh2FElk74Aw "brainfuck – Try It Online")
Requires a trailing newline at the end of the input. A version without this requirement is 6 bytes longer:
# [brainfuck](https://github.com/TryItOnline/brainfuck), 207 bytes
```
,[[[-<+>>>+<<]>-[---<+>]<[[-<]>>]<[-]>>[<<,>>>[-[-<++++++++++>]]++++<[->+<]-[----->-<]<]<]>>>[[>>]+[-<<]>>[[>>]+[<<]>>-]]+[>>]<[-]<[<<]>[->[>>]<+<[<<]>]>[>.>]+[>[-]<,[->+>+<<]>>[----------<.<]>>]<[<<]>-<<<,]
```
[Try it online!](https://tio.run/##PU5BDoNACLzzlRUP2qQ9ED5COGyrthuNTdzUPn8LqykcYCYzMPctpnX6POZSGhFBCswciJRREB0qOa3sC9oQosY0gi7@F6v6MIm5tXoR2XzeLhc7EMzi6AR1RzPKeZwqZScqEQ5oBLcuZ1c0/uAIyMeTWtSeCWtysohaSozQvaAfB0jrEzJ0C/QpZd@2YY/bDLcMl@97meC6j/kH "brainfuck – Try It Online")
Both versions assume all numbers are strictly less than 255.
## Explanation
The tape is laid out as follows:
```
tempinputcopy 85 0 inputcopy number 1 a 1 a 1 r 1 d 0 w 0 o 0 l 0 f 0 ...
```
The "number" cell is equal to 0 if no digits are input, and n+1 if the number n is input. Input is taken at the cell marked "85".
```
,[                     take input and start main loop
 [                     start number input loop
  [-<+>>>+<<]          copy input to tempinputcopy and inputcopy
  >-[---<+>]           put the number 85 in the cell where input was taken
  <[[-<]>>]            test whether input is less than 85; ending position depends on result of comparison
                       (note that digits are 48 through 57 while letters are 97 through 122)
  <[-]>                clean up by zeroing out the cell that didn't already become zero
  >[                   if input was a digit:
   <<,>>               get next input character
   >[-[-<++++++++++>]] multiply current value by 10 and add to current input
   ++++                set number cell to 4 (as part of subtracting 47)
   <[->+<]             add input plus 10*number back to number cell
   -[----->-<]         subtract 51
  <]                   move to cell we would be at if input were a letter
 <]                    move to input cell; this is occupied iff input was a digit
                       part 2: update/output word
 >>>                   move to number cell
 [                     if occupied (number was input):
  [>>]+[-<<]>>         remove existing marker 1s and decrement number cell to true value
  [[>>]+[<<]>>-]       create the correct amount of marker 1s
 ]
 +[>>]<[-]             zero out cell containing next letter from previous word
 <[<<]>                return to inputcopy
 [->[>>]<+<[<<]>]      move input copy to next letter cell
 >[>.>]                output word so far
 +[                    do until newline is read:
  >[-]<                zero out letter cell
  ,.                   input and output next letter or newline
  [->+>+<<]            copy to letter cell and following cell
  >>----------         subtract 10 to compare to newline
 ]
 <[<<]>-               zero out number cell (which was 1 to make copy loop shorter)
 <<<,                  return to input cell and take input
]                      repeat until end of input
```
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), ~~50~~ 48 bytes
*-2 bytes thanks to nwellnhof*
```
{my$l;.map:{$!=S[\d*]=substr $!,0,$l [R||]=~$/}}
```
[Try it online!](https://tio.run/##RcvLCoJAAEbhfU/xC0NUSHmJisweopbmYnRmdHS84JQhaq9utmp34PDVvFGHqeiwFPAx9UVHlLctaH3uieHfgwfbhL5@RfrZgBimZRKF4DYMof8hu3GcvIWmHcTqQimcFC5nkGUCDUfBlVL/qmEtbXKcNPbvSgkcW66v67@MYsQRhc04RIJUwspyhaKsMC/GRZLKLIdtqRlNXw "Perl 6 – Try It Online")
A port of [Arnauld's solution](https://codegolf.stackexchange.com/a/177809/76162). Man, that `R||` trick was a rollercoaster from 'I think this could be possible', to 'nah, it's impossible', to 'kinda maybe possible' and finally 'aha!' 
### Explanation:
```
{my$l;.map:{$!=S[\d*]=substr $!,0,$l [R||]=~$/}}
{                                              }  # Anonymous code block
 my$l;    # Declare the variable $l, which is used for the previous number
      .map:{                                  }  # Map the input list to
            $!=              # $! is used to save the previous word
               S[\d*]=       # Substitute the number for
                      substr $!,0    # A substring of the previous word
                                 ,              # With the length of 
                                           ~$0     # The num if it exists
                                  $l [R||]=        # Otherwise the previous num
```
The `$l [R||]=~$/` part roughly translates to `$l= ~$/||+$l` but... it has the same amount of bytes `:(`. Originally, it saved bytes using an anonymous variable so the `my$l` was gone but that doesn't work since the scope is now the substitution, not the `map` codeblock. Oh well. Anyways, `R` is the reverse metaoperator, so it reverses the arguments of `||`, so the `$l` variable ends up being assigned the new number (`~$/`) if it exists, otherwise itself again.
It could be 47 bytes if Perl 6 didn't throw a kinda redundant compiler error for `=~`.
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~49~~ ~~45~~ 43 bytes
```
$0=$_=$0[/.{0#{p=$_[/\d+/]||p}}/]+$_[/\D+/]
```
[Try it online!](https://tio.run/##HclLDkAwFEDR@duGzhr6LMDMLhBR9Smljc9A6NY9jeE9dzvlRcQwY3XGsBDJjdHtQhWiVFxUz@O8FxX/IQ9A1MgWWtlAqjroBxg14DQbWFYLYamuH0Y9zZCiea07tF13ip35AA "Ruby – Try It Online")
### Explanation
```
$0=                                         #Previous word, assign the value of
   $_=                                      #Current word, assign the value of
      $0[/.{0#{              }}/]           #Starting substring of $0 of length p which is
               p=$_[/\d+/]||p               #defined as a number in the start of $_ if any 
                                 +$_[/\D+/] #Plus any remaining non-digits in $_
```
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~65~~ ~~57~~ ~~55~~ 53 bytes
```
n;b[9];c=b;f(){scanf("%d",&n);gets(c+n)&&f(puts(c));}
```
[Try it online!](https://tio.run/##FYndCoIwGIaPe68ihGSjBNOgYnQl0cH89uN0znBWB@Gtt@rs@aHCEiUX5vUgXWAcb6wM4wJLCqK5nm@CLo34lXckGQzLNirb5YELq@fIaBt4nht2f/yFc7GkJCWqFrVWcMEiovKonYt/mtRTTj1OEYfX6A2OTx1RyoZAjcReaRiL1qHseo8hjPgtpY1tXddjX/oPGS9tTMVQV18 "C (gcc) – Try It Online")
### Explanation:
```
n;                  /* `n` stores the shared prefix length, implicitly 0 */
b[9];               /* int[] buffer we read into, we need 12+1 bytes for the
                       largest words, this buffer is 9*4=36 bytes */
c=b;                /* if we use `b` in pointer arithmetic it would be an int*,
                       but we want to address individual bytes, so we need to
                       store the address as an integer. */
f() {               /* the unpacking function */
    scanf("%d",&n); /* read the common prefix length, if scanf fails because no
                       new prefix length is given then `n`s value will remain
                       the same, which is exactly what we want!  :-) */
    gets(c+n)       /* read the suffix part, the first `n` characters are the
                       common prefix */
        &&          /* short-circuit, so if the gets fails the next part is not
                       executed */
    f(puts(c));     /* print the word that was extracted and call `f`
                       recursively to handle the next word */
}
```
[Answer]
## Python 3.6+, ~~172~~ ~~195~~ ~~156~~ ~~123~~ ~~122~~ ~~121~~ 104 bytes
```
import re
def f(l,n=0,w=""):
 for s in l:t=re.match("\d*",s)[0];n=int(t or n);w=w[:n]+s[len(t):];yield w
```
* -12 bytes thanks to [Bubbler](https://codegolf.stackexchange.com/users/78410/bubbler)
* -5 bytes thanks to [Dennis](https://codegolf.stackexchange.com/users/12012/dennis)
[Try it online!](https://tio.run/##RY5BboMwEEX3c4oRK7tFKAqVWoF8i@woCxoPxYozWPYkDqen0Ejt38yX/tPohUWmmet1ddcwR8FIYGnEUfmSzaHMpih0AzjOERM6Rt@IiVRdBzlPqvi0L0WZdHfoWzaORQluIOs2m9w13L@mzhMr0U3fLo68xbx6NNj1kCfnCU/xRtv7LRKXZ9njK3oIsVWOw02UrlLwbrv6l6DHmYL801@RhgvAn@Mmr59riLtU0uswwHGCmiw4/oYERw@1c2lv0d6HeIGPBG959iO83yn9AA "Python 3 – Try It Online")
### Explanation
I caved, and used Regular Expressions. This saved at least 17 bytes. :
```
t=re.match("\d*",s)[0]
```
When the string doesn't begin with a digit at all, the length of this string will be `0`. This means that:
```
n=int(t or n)
```
will be `n` if `t` is empty, and `int(t)` otherwise.
```
w=w[:n]+s[len(t):]
```
removes the number that the regular expression found from `s` (if there's no number found, it'll remove `0` characters, leaving `s` untruncated) and replaces all but the first `n` characters of the previous word with the current word fragment; and:
```
yield w
```
outputs the current word.
[Answer]
## Haskell, ~~82~~ 81 bytes
```
tail.map concat.scanl p["",""]
p[n,l]a|[(i,r)]<-reads a=[take i$n++l,r]|1<2=[n,a]
```
Takes and returns a list of strings.
[Try it online!](https://tio.run/##dYxBbsIwFET3nGJksWhFQCRUahfkJGkWH9uJP/6xLTuCDWevmx6gi5FGevPGUfFWpLr@u67EclooQcegaT0VTUGQBqUapcZdGkIjI72GN27y@3g9ZkumgPphJW/B@3A4SJPHV3vt@m1LY12IA3qYuAOQMocVe7gtz5g3VRGhc7hYAw4zCjrBhbn8tWwelD2@Cj6eUSZ8PmxR/93cNPSN0BqLaYZjnO9esISIDRk7zY7vHu1ZVP3Rk9Bc6lGn9As "Haskell – Try It Online")
```
        scanl p["",""]        -- fold function 'p' into the input list starting with
                              -- a list of two empty strings and collect the
                              -- intermediate results in a list
  p [n,l] a                   -- 1st string of the list 'n' is the part taken form the last word
                              -- 2nd string of the list 'l' is the part from the current line
                              -- 'a' is the code from the next line
     |[(i,r)]<-reads a        -- if 'a' can be parsed as an integer 'i' and a string 'r'
       =[take i$n++l,r]       -- go on with the first 'i' chars from the last line (-> 'n' and 'l' concatenated) and the new ending 'r'
     |1<2                     -- if parsing is not possible
       =[n,a]                 -- go on with the previous beginning of the word 'n' and the new end 'a'
                              -- e.g. [         "aa",     "2h",      "3ed",       "ing"       ] 
                              -- ->   [["",""],["","aa"],["aa","h"],["aah","ed"],["aah","ing"]]
  map concat                  -- concatenate each sublist
tail                          -- drop first element. 'scanl' saves the initial value in the list of intermediate results. 
```
Edit: -1 byte thanks to @Nitrodon.
[Answer]
# Japt, ~~19~~ ~~18~~ 17 bytes
Initially inspired by [Arnauld's JS solution](https://codegolf.stackexchange.com/a/177809/58974).
```
;£=¯V=XkB ªV +XoB
```
[Try it](https://ethproductions.github.io/japt/?v=1.4.6&code=O6M9r1Y9WGtCIKpWICtYb0I=&input=WyJhYmMiLCJjYmEiLCIxZGUiLCJmZyIsImhpIiwiMGprbCIsIm1ubyIsImFiY2RlZmdoaWprIiwiMTBsIl0KLVM=)
```
                      :Implicit input of string array U
 £                    :Map each X
   ¯                  :  Slice U to index
      Xk              :    Remove from X
;       B             :     The lowercase alphabet (leaving only the digits or an empty string, which is falsey)
          ªV          :    Logical OR with V (initially 0)
    V=                :    Assign the result to V for the next iteration
             +        :  Append
              Xo      :  Remove everything from X, except
;               B     :   The lowercase alphabet
  =                   :  Reassign the resulting string to U for the next iteration
    
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 16 bytes
```
⁹fØDVo©®⁸ḣ;ḟØDµ\
```
[Try it online!](https://tio.run/##y0rNyan8//9R4860wzNcwvIPrTy07lHjjoc7Fls/3DEfKHRoa8z/h7u3KBxuV4hUeLhj@6OGOQrBBTmZJToKyYk5OQpppXnJJZn5eToKWfmZeXr//ycmchllcBmnpnBl5qVzFXMZ5XAZZ2YWg1hFKWWJRdlcFsVcJuX5OWlc5mWpxQA "Jelly – Try It Online")
### How it works
```
⁹fØDVo©®⁸ḣ;ḟØDµ\  Main link. Argument: A (array of strings)
              µ\  Cumulatively reduce A by the link to the left.
⁹                     Yield the right argument.
  ØD                  Yield "0123456789".
 f                    Filter; keep only digits.
    V                 Eval the result. An empty string yields 0.
     o©               Perform logical OR and copy the result to the register.
       ®              Yield the value in the register (initially 0).
        ⁸ḣ            Head; keep that many character of the left argument.
          ;           Concatenate the result and the right argument.
            ØD        Yield "0123456789".
           ḟ          Filterfalse; keep only non-digits.
```
[Answer]
# [Groovy](http://groovy-lang.org/), 74 bytes
```
{w="";d=0;it.replaceAll(/(\d*)(.+)/){d=(it[1]?:d)as int;w=w[0..<d]+it[2]}}
```
[Try it online!](https://tio.run/##RYzLboMwEEX3fAXyyk4kHkmkRCVW1O/IsDAeA07cARkEqqJ8Ox21iy7PuVeni8OwfG8m1akwBujQAx0dAnnqgCYWgYX30x9EXEx8Al0YTusQWqDz4iaRNL@BxgLZhjMlOqCWC70HKh5PjnzRAMQPdG3X@wdHyiKIxOrttWohKtRF5ecsujEY6z5DkLkE3CmZ7VWuXqiln@9lfftAZabU01yter0XWXbFes/ToX6/tzHyECi10qjkHxq1/QA "Groovy – Try It Online")
### Explanation:
```
{                                                                        }  Closure, sole argument = it
 w="";d=0;                                                                  Initialize variables
          it.replaceAll(/(\d*)(.+)/){                                   }   Replace every line (since this matches every line) and implicitly return. Loop variable is again it
                                     d=(it[1]?:d)as int;                    If a number is matched, set d to the number as an integer, else keep the value
                                                        w=w[0..<d]+it[2]    Set w to the first d characters of w, plus the matched string
```
[Answer]
# [Python 2](https://docs.python.org/2/), 118 bytes
```
import re
n=0
l=input()
o=l.pop(0)
print o
for i in l:(N,x),=re.findall('(\d*)(.+)',i);n=int(N or n);o=o[:n]+x;print o
```
[Try it online!](https://tio.run/##LYxLDoMgFEXnrIIZ0BJjO9SwBTdgHfhDn@J7hNDErp5K08k9k3uO/8SV8JkSHJ5C5GFmaErmDKB/R6kYGVd48rJUzAfAyIlZChw4IHeVbPSptAlzYQGn3jkp5Gu6KVncldCgarxCUTb8UlDVZKitsLuf9b@VUiv6YRSai3HoMx7TnGGXvCvkLbfdZR5IGdd/mu2ywrb/hNKJ7gs "Python 2 – Try It Online")
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), 69 bytes
```
+`((\d+).*¶)(\D)
$1$2$3
\d+
$*
+m`^((.)*(.).*¶(?<-2>.)*)(?(2)$)1
$1$3
```
[Try it online!](https://tio.run/##FYs7DoMwEET7OccWu7aCsGlRaDgGijDYgPlFinK2HCAXM6aYYt68@YRvPF1KumfuvJZC/X/CXSsgQ5YqZAhS0Ef/Yi5E5dwON/XDPnMXbtgKibkPVUpuGDEODsYHTDOWiHLddhznG3nyYZqXuG4w5X4B "Retina 0.8.2 – Try It Online") Link includes harder test cases. Explanation:
```
+`((\d+).*¶)(\D)
$1$2$3
```
For all lines that begin with letters, copy the number from the previous line, looping until all lines begin with a number.
```
\d+
$*
```
Convert the number to unary.
```
+m`^((.)*(.).*¶(?<-2>.)*)(?(2)$)1
$1$3
```
Use balancing groups to replace all `1`s with the corresponding letter from the previous line. (This turns out to be slightly golfier than replacing all runs of `1`s.)
[Answer]
# [Red](http://www.red-lang.org), 143 bytes
```
func[b][a: charset[#"a"-#"z"]u: b/1 n: 0 foreach c b[parse c[copy m to a
p: copy s to end(if p<> c[n: do m]print u: rejoin[copy/part u n s])]]]
```
[Try it online!](https://tio.run/##LY5BTsMwEEX3PsVX2MAC0TSkKRXiEGyjLBx7nLhx7MhOi6Dq2cu4sLDk73n/eSLp2yfpthPmcDMnr9q@a@UBapQx0do@FLJ4fih@iu50QP9Swh@wgQmRpBqh0LdLBqFaFZZvzFgDpFhYkGPKkbx@tAbL@wdTXNcBc7dE61ewM9IxWH9vv7CK3@CRuqeu624GaXF2FRfZK6F6KUpNwgxitGJznJyYfRA80mSG0R4nUW7cFZ6@nPUkxN8XRSHEv@ciJbYjKtKwfuDltg6VtSnfoj7LOGGf8PoVnEFzpoRqGBH57EZsOZ3DQC4jZY@tRKUkauYnrBStdDgl7HLLrJhkggue0HCeF4qUe0xXXgePhlfYR7wlNHmTmXjRskx3erGKXewl1Bo79436Pme4jtjdLa8jalbkwP1rgeL2Cw "Red – Try It Online")
[Answer]
# [Perl 5](https://www.perl.org/) `-p`, ~~45~~ 41 bytes
```
s:\d*:substr($p,0,$l=$&+$l*/^\D/):e;$p=$_
```
[Try it online!](https://tio.run/##FcdRCsIwDADQ/5wjiM7JxqYolf15jKFUG2cxrKGZ8/ZG/XtPKPPOTF0fCqevq055iVLWJXKHizVyUZ37U7VydETp8GLmPTQPaClAHAdQaBjaGPWvHGafn3BQ2L4T32E/k0J9S4GGXz9JpphGtY18AQ "Perl 5 – Try It Online")
Explanation:
```
s:\d*:substr($p,0,$l=$&+$l*/^\D/):e;$p=$_ Full program, implicit input
s:   :                           :e;      Replace
  \d*                                       Any number of digits
      substr($p,0,              )           By a prefix of $p (previous result or "")
                  $l=  +                      With a length (assigned to $l) of the sum
                     $&                         of the matched digits
                          *                     and the product
                        $l                        of $l (previous length or 0)
                           /^\D/                  and whether there is no number in the beginning (1 or 0)
                                                (product is $l if no number)
                                    $p=$_ Assign output to $p
                                          Implicit output
```
[Answer]
# [Java (JDK)](http://jdk.java.net/), 150 bytes
```
a->{String p="",s[];for(int n=0,i=0;i<a.length;a[i]=p=p.substring(0,n=s.length<1?n:new Short(s[0]))+a[i++].replaceAll("\\d",""))s=a[i].split("\\D+");}
```
[Try it online!](https://tio.run/##fVDBitswFLznKwZBwW68wtkttMTxlqW99pRj1gfFlm05smT05IRlybenVuINhdIKhKQ3b@bNqBNH8dBVh4vqB@s8uunNR680/5wt/qrVoym9siaApRZE@CWUwfsCGMa9ViXICz8dR6sq9BMWbb1TptkVEK6h@NoK/LCGxl66zQf6jBr5RTw8v98qGHLGEtoVWW1dpIyHydNE5WmmNoJraRrfZmKninzIB07jnq60KE1MTjO@WX03ayNP2LZTioh2aRHHy4m0XBbcyUGLUr5oHbHX14oljMUx5UGS06CVD@WfSxZn50t29XwP4iV5Qj5HCYsJgccWT7JC8E541HhSisLNVUfhDvhG@HKyusbXoySW/EHdlyj3AqtKom7QKqTdQaM3FhNUybppVXfAKtVsJp1vfsLHzJ8VHK1vvuK7rWksTtZVwWqAPmJhyjS3bN/Iy57b0fNhEvJ1xD7RGizBi3Pijbi3twnRVSi@E2suylIOfq7/S0@b6L9C50XY58tv "Java (JDK) – Try It Online")
[Answer]
# [Scala](http://www.scala-lang.org/), 226 129 102 bytes
Thanks @ASCII-only for their work here (and for the Groovy answer).
```
s=>{var(w,d,r)=("",0,"(\\d*)(.+)".r)
s map(_ match{case r(a,b)=>{if(a>"")d=a.toInt
w=w.take(d)+b}
w})}
```
[Try it online!](https://tio.run/##TY5NS8QwEIbv/RUhp8QNpVXBReiCF0HQk8fdRab52KbtpiWJW6H0t9eJsOrlybzDZJ4JEnpYh7rVMpI3sI7or6idCuRpHMmcXcAT8/j86WS0gyv3rzbE/Xv01p2O4n84VmuodjPOs0ko4XnFKBWFoOxwUDec5RtOc8@zQM4wsg9klM0sIWjiGYia42drGOwo5aqCPA4vLmZTNeUROs0U39RLNi18WUf0xd4xw5KfUQAq6G2DuNMKidcgQ2r2qWltuGav8L4Oq22K99PQG3wfLjpQznl23fxX/TpqiYOyTqpSaaRJksYiirZLnrMbkDiotDk1tk2asuh/Fi/rNw "Scala – Try It Online")
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), ~~20~~ ~~19~~ ~~17~~ 16 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
õUvyþDdi£U}Xyá«=
```
[Try it online](https://tio.run/##yy9OTMpM/f//8NbQssrD@1xSMg8tDq2NqDy88NBq2///o5USE5V0lIwygIRxagqQzMxLB5LFIMEckGBmZjGMX5RSlliUDWRZgLgm5fk5aUDavCy1WCkWAA) or [verify all test cases](https://tio.run/##yy9OTMpM/V@m5OkXEBpipaBkX@mio@QfGgLh6fw/vDW0rPLwPpeUzEOLQ2sjKg8vPLTa9n/toW32/6OjlRITlXSUjDKAhHFqCpDMzEsHksUgwRyQYGZmMYxflFKWWJQNZFmAuCbl@TlpQNq8LLVYKVZHAWhUUjKQn5wEMtEwJRVIpoHMysgEEgZZ2SDjcvPygSRQYUpqWnpGZhbINEODHKXYWAA).
**Explanation:**
```
õ               # Push an empty string ""
 U              # Pop and store it in variable `X`
v               # Loop `y` over the (implicit) input-list:
 yþ             #  Push `y`, and leave only the digits (let's call it `n`)
   Ddi  }       #  If it's a non-negative integer (thus NOT an empty string ""):
      £         #   Pop and push the first `n` characters of the string
       U        #   Pop and store it in variable `X`
         X      #  Push variable `X`
          yá    #  Push `y`, and leave only the letters
            «   #  Merge them together
             =  #  Print it with trailing newline (without popping)
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 27 bytes
```
f€ȯ@\V,ɗḟ€ɗØDZẎḊṖḣ2/Ż;"f€Øa
```
[Try it online!](https://tio.run/##y0rNyan8/z/tUdOaE@sdYsJ0Tk5/uGM@kHdy@uEZLlEPd/U93NH1cOe0hzsWG@kf3W2tBFJ5eEbi/8Pt2vpA5tFJD3fO@P8/Wj0xKVldR0E9OSkRRBmmpIKotHQQmZEJIg2ysnNAdG5ePogCqk9JTUvPyMzKBmswyFGPBQA "Jelly – Try It Online")
[Answer]
# [Groovy](http://groovy-lang.org/), ~~103~~ 99 bytes
```
{w=it[0];d=0;it.collect{m=it=~/(\d+)(.+)/;i=m.find()?{d=m[0][1] as int;m[0][2]}():it;w=w[0..<d]+i}}
```
[Try it online!](https://tio.run/##VU7daoMwGL3vUxy8ShBStYONZmEPYr2IiT9fjVpMUIq4V3euN2N355/TTOM4P3cNhUhrZC0ulQUNDTwyhwuR/0WTnfXU4cPjbRldjfe58pHwD0eBRYj4qXwNlAam1EhthbpBS0junUM/jDgsW9VNS/cOaeL@dY3a10VRyJNCWpVICsKMzlUmrP0hq@8zu9mYMxHzsyTVi5oGy/jXalV/dPK0gPbH5yBfNCs2xq8U5KKWPBHi0xYxbdv@mI6IG2CY5qc/UvL9Bw "Groovy – Try It Online")
[Answer]
# Common Lisp, 181 bytes
```
(do(w(p 0))((not(setf g(read-line t()))))(multiple-value-bind(a b)(parse-integer g :junk-allowed t)(setf p(or a p)w(concatenate'string(subseq w 0 p)(subseq g b)))(format t"~a~%"w)))
```
[Try it online!](https://tio.run/##NU3RagMxDHv3V5jCmPMQKO1gY3/ju/huWdMki32Xt/76LWXMIJCEJM8paj0OCoU6VTw7R5SLkYotuFITDj7FLGjknkf3LVmsSfzOaRM/xRyIcXJUuan4mE1Wabji5/eWb55TKl0CmvubrFQaMlbXaS55ZpM88KrWYl5Jt0nlBzueR@JfrWN9PF5Ku7OhnR78eDn1YR0HM1y@4CoBRhsULgmuMeqTtbBzu8GHwlsvaYH3XRR@AQ)
Ungolfed:
```
(do (w (p 0))   ; w previous word, p previous integer prefix (initialized to 0)
    ((not (setf g (read-line t ()))))   ; read a line into new variable g
                                        ; and if null terminate: 
  (multiple-value-bind (a b)            ; let a, b the current integer prefix
      (parse-integer g :junk-allowed t) ; and the position after the prefix
    (setf p (or a p)                    ; set p to a (if nil (no numeric prefix) to 0)
          w (concatenate 'string        ; set w to the concatenation of prefix
             (subseq w 0 p)             ; characters from the previous word 
             (subseq g b)))             ; and the rest of the current line
    (format t"~a~%"w)))                 ; print the current word
```
As usual, the long identifers of Common Lisp make it non particularly suitable for PPCG.
[Answer]
# [Python 2](https://docs.python.org/2/), ~~101~~ ~~100~~ 99 bytes
```
import re
s=n='0'
for t in input():(m,w),=re.findall('(\d*)(.+)',t);n=m or n;s=s[:int(n)]+w;print s
```
[Try it online!](https://tio.run/##TY89b8IwEIbn@lecxHB2iRDQSq1AGenapRtlMMQhJo4dnQ0pvz71pZVaybr39X35cX9PTfDr8RQqAyUQIo626wMlICNi6UtcoqgDQQLr8@mvSaqN7IpBFSWZRW19pZ2TKD@rRyUXc4VFUltfdpCH/DaWcb@xPkmvDvNh21P2EMf8jhga6wx80NVsxEOie44P5sucgGGy/@nFGYqcPpk@we79bUcUiDuPZHQrZrVUQszgt1cf8/RRwyr/pj5DY2F5aR10PkAuVaY@N/bSwmrpcBF7Z5NEQDXuUWssANcNxydTsVh/ZolTwU0Fa@Nfiqqbppbt65R4HoKr2bzcTMSD2DMN3zMQS2ZiqaetjeXIcKyZj@Uf4jSQKQ/f "Python 2 – Try It Online")
[Answer]
# [C# (Visual C# Interactive Compiler)](http://www.mono-project.com/docs/about-mono/releases/5.0.0/#csc), 134 bytes
```
a=>{int l=0,m,n;var p="";return a.Select(s=>{for(m=n=0;s[m]<58;n=n*10+s[m++]-48);return p=p.Substring(0,l=m>0?n:l)+s.Substring(m);});}
```
[Try it online!](https://tio.run/##dVFNa8MgGL7nV0hOyZKWdOtYmTVjhw12G3S3koMxprFVU9S0jJLfnhmC0rINPDxf@j68Ej0jmg3vnSTrjzfZCapwyelaG8XkLk//0HJQAzRglF@YNICjLBWphCeswBGFIVTUdEoCPN9QTomJtA3WrYoEkiiDeiuK9eMKSiTvFlliaZIUs@UqdveO6DjfdOU0K8pSjkSevchnHif6yhAx7O0ZYBBMyrbYFsBQbTRAQNIzuJIvAbiRRg5AiHGYTui@ceiBVg7aqIPaB7kPMqZ/26qyezg4uvLG8tzy2pGnE52MPv2nWElclpS@5KKiDta@WcMcyvYHX07I1kH7VkXrXcP2vtYi4258b/dnP4di0kTjD44LBExOi4zHOp@2mYnqaFTi@Vf7qhT@juIYBv3wAw "C# (Visual C# Interactive Compiler) – Try It Online")
-9 bytes thanks to @ASCIIOnly!
Less golfed...
```
// a is an input list of strings
a=>{
  // l: last prefix length
  // m: current number of digits
  // n: current prefix length
  int l=0,m,n;
  // previous word
  var p="";
  // run a LINQ select against the input
  // s is the current word
  return a.Select(s=>{
    // nibble digits from start of the
    // current word to build up the
    // current prefix length
    for(m=n=0;
      s[m]<58;
      n=n*10+s[m++]-48);
    // append the prefix from the
    // previous word to the current
    // word and capture values
    // for the next iteration
    return
      p=p.Substring(0,l=m>0?n:l)+
      s.Substring(m);
  });
}
```
]