15
\$\begingroup\$

Challenge

Given a string describing a cutting rule and another string, cut parts out of the second string using the rule described by the first string.

Both strings will consist of letters a-z or A-Z, whichever one you choose (they don't have to be represented the same way). The way the second string is to be modified is described below:

Algorithm

Take the first string and imagine filling in the gaps between non-adjacent (increasing) letters with =; for example, abcfg => abc==fg. Then, line up the two strings and return all characters from the first string that aren't above an equal sign. For example, given abcfg and qrstuvw as inputs:

qrstuvw - Modify
abc==fg - Modifier

qrs--vw -> qrsvw

If the modifier is shorter after filling with equal signs, all trailing characters in the second string should be included. If the modifier is longer, the trailing characters are ignored.

The modifier isn't guaranteed to be sorted.

Test Cases

abcfg, qrstuvw -> qrsvw
abqrs, qwertyuiopasdfghjklzxcvbnm -> qwjklzxcvbnm
za, qr -> qr
azazaz, qwertyuioplkjhgfdsazxcvbnmnbvcxzasdfghjklpoiuytrewq -> qmn

Reference Implementation (used to generate test cases) -> TIO

Rules

  • Standard Loopholes Apply
  • You may take input as two strings, two lists of characters, a matrix of characters, etc. (any other reasonable format is acceptable)
  • You may output as a string or a list of characters (or some other standard format for strings)
  • This is , so the shortest answer in bytes in each language is declared the winner for its language. No answer will be accepted.
  • Either string may be empty.

Happy Golfing!

Inspired by Kevin Cruijssen's recent two challenges, "There, I fixed it (with tape/rope)"

\$\endgroup\$
  • 4
    \$\begingroup\$ There, I fixed it (with tape), There, I fixed it (with rope) \$\endgroup\$ – Erik the Outgolfer Mar 8 '18 at 14:23
  • 2
    \$\begingroup\$ very common trend im seeing here \$\endgroup\$ – L_Church Mar 8 '18 at 14:24
  • \$\begingroup\$ @L_Church challenges sometimes follow trends. two related challenges were posted so I decided to continue along the trend :D I was going to post another "I fixed it" challenge but a) I like breaking things better 2) I can't think of another creative and distinct enough "fixed it" idea :P \$\endgroup\$ – HyperNeutrino Mar 8 '18 at 14:27
  • 16
    \$\begingroup\$ Next challenge: There, I blew it up (with a segfault) \$\endgroup\$ – Magic Octopus Urn Mar 8 '18 at 14:49
  • 1
    \$\begingroup\$ @MagicOctopusUrn Someone beat you to it :( \$\endgroup\$ – caird coinheringaahing Mar 8 '18 at 16:39

13 Answers 13

6
\$\begingroup\$

JavaScript (ES6), 81 80 bytes

Takes input in currying syntax (modify)(modifier).

s=>g=([c,...a],d=i=0,x=s[k=parseInt(c,36),i+=c?d&&(k-d+26)%26:1])=>x?x+g(a,k):''

Try it online!

Commented

s =>                       // outer function, taking the string s to modify
  g = (                    // recursive inner function g(), taking:
    [c, ...a],             //   c = current modifier character; a[] = remaining characters
    d = i = 0,             //   d = code of previous modifier character; i = pointer in s
    x = s[                 //   x = i-th character of s
      k = parseInt(c, 36), //     k = code of the current modifier character in [10..35]
      i += c ?             //     update i; if c is defined:
        d &&               //       if d = 0, let i unchanged
        (k - d + 26) % 26  //       otherwise, add the difference between k and d (mod 26)
      :                    //     else:
        1                  //       just pick the next character by adding 1
    ]                      //   end of character lookup in s
  ) =>                     //
    x ?                    // if x is defined:
      x + g(a, k)          //   append x and do a recursive call to g()
    :                      // else:
      ''                   //   stop recursion
\$\endgroup\$
3
\$\begingroup\$

Python 3, 99 bytes

lambda a,b:[x for x,y in zip(a,''.join(d+(ord(c)+~ord(d))%26*'='for c,d in zip(b[1:],b))+a)if'='<y]

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Jelly, 14 bytes

OI’R¬⁸żFḣL}aḟ0

A dyadic link accepting the modifier as a list of characters on the left and the list of characters to modify on the right returning a lists of characters.

Try it online!

How?

OI’R¬⁸żFḣL}aḟ0 - Link list of characters Modifier, list of characters InStr
               -                       e.g.  ['a','c','g','a'], ['n','m','l','k','j']
O              - ordinals of Modifier        [97,99,103,97]
 I             - incremental differences     [2,4,-6]
  ’            - decrement                   [1,3,-7]
   R           - range                       [[1],[1,2,3],[]]
    ¬          - NOT (vectorises)            [[0],[0,0,0],[]]
     ⁸         - chain's left argument, Modifier
      ż        - zip together                [['a',[0]],['c',[0,0,0]],['g',[]],['a']]
       F       - flatten                     ['a',0,'c',0,0,0,'g','a']
         L}    - length of right (InStr)     5
        ḣ      - head to index               ['a',0,'c',0,0] (if shorter or equal, no effect)
           a   - AND with InStr (vectorises) ['n',0,'l',0,0]
            ḟ0 - filter out zeros            ['n','l']
\$\endgroup\$
  • \$\begingroup\$ Used the ¬ trick in my answer. :) (we technically have the same algorithm, but you did shorter, well done!) \$\endgroup\$ – Erik the Outgolfer Mar 8 '18 at 18:09
  • \$\begingroup\$ Oh yeah, I was gonna comment about ¬, but forgot when I did a mobile phone fat-finger post of a not-yet-ready 13 byte attempt. \$\endgroup\$ – Jonathan Allan Mar 8 '18 at 18:12
3
\$\begingroup\$

05AB1E, 20 17 bytes

ćsv¹Ç¥Nè<yú«}SðÊÏ

Try it online!


Calculates the ASCII distance between each char, prepending that many spaces if it's positive. Negative distance results in appending 0 spaces, as per the spec. After that, I push all characters at the same indices in string 2 as the spaces in the first manipulated string.


Input: [azaz,qwertyuiopasdfghjklzxcvbnm]
--------------------------------------------------------------------------------

ćs                # Remove head, swap                           | [a, zaz]
  v               # Iterate...                                  | ............
   ¹Ç¥            # Push deltas between each char of string 1   | [a,[25,-25,25,-25]]
      Nè          # Push delta at index...                      | [a, 25]
        <         # Decrement (for 1-indexed answer)            | [a, 24]
         y        # Push current char in iteration...           | [a, 24, z]
          ú       # Append b spaces to a...                     | [a, '(spaces)z']
           «      # Concat                                      | [a(spaces)z]
            }     # End loop.                                   | [a(spaces)za(spaces)z]
             SðÊ  # Split, push 1 for non-space elements.       | [Long array of 1/0]
                Ï # Push chars from 2 that aren't spaces in 1.  | ['qmn']

90% sure I can lose another 2-3 bytes by not using spaces, but pushing the char at index N. Still working on this variant at the moment... What my "better idea" ended up as:

05AB1E, 18 bytes

Ç¥ε1‚Z}ηO0¸ìʒ²g‹}è

Try it online!

I feel like I'm missing something, if you see improvements on ε1‚Z}, ʒ²g‹} or 0¸ì lmk...

Ç¥ε1‚Z}ηO0¸ìè was 13, but it wraps when n > |input_2| to input_2[n%|input_2|]...

\$\endgroup\$
  • \$\begingroup\$ Your second version could be Ç¥ε1M}.¥ʒ²g‹}è, but none of the three versions seem to work for these inputs. \$\endgroup\$ – Emigna Mar 9 '18 at 7:51
  • \$\begingroup\$ The version above could be fixed by adding IgÅ1«, but maybe there's a better way? \$\endgroup\$ – Emigna Mar 9 '18 at 11:24
2
\$\begingroup\$

Stax, 15 bytes

Ç«|¢Äα•è@╟╣i`vF

Run and debug it

This is the ascii representation.

:-Z+{v0|Mt|cB]pFp
  1. Get pairwise differences.
  2. Prepend a zero.
  3. Foreach difference, repeat
    1. Subtract 1, and take maximum with zero.
    2. Remove that many characters from the beginning of string.
    3. Stop if the string is empty.
  4. Print the rest of the string.
\$\endgroup\$
  • 1
    \$\begingroup\$ I like how the code says ╟╣i \$\endgroup\$ – Uriel Mar 9 '18 at 0:30
2
\$\begingroup\$

JavaScript (ES6), 79 bytes

f=([t,...T],s,z=T[0])=>z&&s?s[0]+f(T,s.slice(t>z||(parseInt(t+z,36)-370)%37)):s

Uses the same algorithm for calculating distance between letters as my last answer.

Test cases:

f=([t,...T],s,z=T[0])=>z&&s?s[0]+f(T,s.slice(t>z||(parseInt(t+z,36)-370)%37)):s

console.log(f('abcfg','qrstuvw')) // -> qrsvw
console.log(f('abqrs','qwertyuiopasdfghjklzxcvbnm')) // -> qwjklzxcvbnm
console.log(f('za','qr')) // -> qr
console.log(f('azazaz','qwertyuioplkjhgfdsazxcvbnmnbvcxzasdfghjklpoiuytrewq')) // -> qmn

\$\endgroup\$
2
\$\begingroup\$

APL (Dyalog Classic), 35 34 32 bytes

{⍵∩⍨⊃¨↓∘⍵¨+\0,1⌈(-2-/⎕ucs⍺),=⍨⍵}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

K (ngn/k), 27 24 25 bytes

{y[+\0,1|1_-':x,!#y]^" "}

Try it online!

{y[+\0,1|1_-':x,!#y]^" "}

{                       } function with x and y as arguments
                 #y       the length of y
                !#y       0 1 2 ... (#y)-1
              x,          x concatenated with
           -':            differences between pairs
         1_               rm extra leading item
       1|                 max between 1 and
     0,                   prepend 0
   +\                     partial sums
 y[                ]      index y with that
                    ^" "  rm spaces due to out-of-bounds indexing
\$\endgroup\$
1
\$\begingroup\$

Haskell, 49 bytes

(x:r)#(y:n:s)=x:drop(length[y..n]-2)r#(n:s)
r#_=r

Try it online!

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

Perl 5, 45 bytes

s/./v0.$;x(ord($')-1-ord$&)/eg;$_|=<>;s/\W//g

Try it online!

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

Ruby, 68 64 bytes

->m,z,i=1{z[i,[0,m[i].ord+~m[i-1].ord].max]&&='';m[i+=1]?redo:z}

Try it online!

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

Charcoal, 29 28 bytes

⭆η×ιI§⁺⭆θ⁺×0∧μ⊖⁻℅λ℅§θ⊖μ1⭆η1κ

Try it online! Link is to verbose version of code. Based on my answer to There, I fixed it with tape. Explanation:

       ⭆θ⁺×0∧μ⊖⁻℅λ℅§θ⊖μ1        Fix it with tape, but map to 1s and 0s
      ⁺                 ⭆η1     Append extra 1s just in case
⭆η                              Map over the second string
     §                     κ    Get the character from the fixed string
    I                           Cast to integer
  ×ι                            Repeat the current character that many times
                                Implicitly print

Note: This should be 28 bytes, but And is broken at time of writing.

\$\endgroup\$
0
\$\begingroup\$

Java 8, 117 bytes

a->b->{for(int i=0,j;++i<a.length;b=j>0&b.length()>=i+j?b.substring(0,i)+b.substring(i+j):b)j=a[i]+~a[i-1];return b;}

Explanation:

Try it online.

a->b->{                   // Method with char-array + String parameters and String return
  for(int i=0,j;++i<a.length;
                          //  Loop `i` in range [1; length_of_array)
      b=                  //    After every iteration: change the String-input to:
        j>0               //     If `j` is larger than 0,
        &b.length()>=i+j? //     and the length of `b` is larger or equal to `i+j`:
         b.substring(0,i) //      Take the substring [0; i)
         +b.substring(i+j)//      + the substring [i+j; end_of_string]
        :                 //     Else:
         b)               //      Leave `b` the same
    j=a[i]+~a[i-1];       //   Set `j` to the difference between two adjacent chars - 1
  return b;}              //  Return the modified input-String
\$\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.