66
\$\begingroup\$

Introduction

The Enigma was one of the first electro-mechanical rotor cipher machines used in World War II. That means that after a single letter is coded, it would change the key for the next letter. This was considered unbreakable by the Germans, due to the enormous key space. Even brute-forcing was almost impossible. However, there was a design error in the Enigma. Encrypting a letter would never result into itself. That means that the letter A can encrypt to every letter except the letter A.

Let's take an example of a coded message:

BHGEFXWFTIUPITHHLPETTTCLOEWOELMRXXPAKAXMAMTXXUDLTWTNHKELEPPLHPRQ

A typical German word was WETTERBERICHT, or weather report in English. With the principe above, we can determine at which locations the word could possibly be:

BHGEFXWFTIUPITHHLPETTTCLOEWOELMRXXPAKAXMAMTXXUDLTWTNHKELEPPLHPRQ
WETTERBERICHT
         ^

This is not possible, because the I can't be encrypted to itself, so we move on 1 place:

BHGEFXWFTIUPITHHLPETTTCLOEWOELMRXXPAKAXMAMTXXUDLTWTNHKELEPPLHPRQ
 WETTERBERICHT
             ^

This is also not possible, so we move another place again:

BHGEFXWFTIUPITHHLPETTTCLOEWOELMRXXPAKAXMAMTXXUDLTWTNHKELEPPLHPRQ
  WETTERBERICHT
   ^

This again is not possible. In fact, the first possible occurence of WETTERBERICHT is:

BHGEFXWFTIUPITHHLPETTTCLOEWOELMRXXPAKAXMAMTXXUDLTWTNHKELEPPLHPRQ
             WETTERBERICHT
0123456789012345678901234567890123456789012345678901234567890123
             ^
             13

So, we return the 0-indexed position of the first possible occurence, which is 13.

The Task

  • Given a coded message and a word, find the index of the first possible occurence.
  • Assume that only basic uppercase alphabetic characters will be used (ABCDEFGHIJKLMNOPQRSTUVWXYZ).
  • If no occurence is found, you can output any negative integer, character, or nothing (e.g. -1, X).
  • Input may be accepted as argument, on seperate newlines, lists or anything else.
  • This is , so the submission with the least amount of bytes wins!

Test cases

Input: BHGEFXWFTIUPITHHLPETTTCLOEWOELM, WETTERBERICHT
Output: 13

Input: ABCDEFGHIJKL, HELLO
Output: 0

Input: EEEEEEEEEEEE, HELLO
Output: -1

Input: XEEFSLBSELDJMADNADKDPSSPRNEBWIENPF, DEUTSCHLAND
Output: 11

Input: HKKH, JJJJJ
Output: -1
\$\endgroup\$
  • 1
    \$\begingroup\$ Umm, why does the encoded string change in the middle of the example? \$\endgroup\$ – Doorknob Dec 30 '15 at 15:56
  • 36
    \$\begingroup\$ @Doorknob冰 ¯\_(ツ)_/¯ \$\endgroup\$ – Adnan Dec 30 '15 at 15:59
  • \$\begingroup\$ There are issues with the introduction: 1. it wasn't considered unbreakable because of the key space, but because of the system that a letter changes what it is translated to 2. "Encrypting a letter would never result into itself." - yes it would, after the number of available characters it would have to repeat one. \$\endgroup\$ – Zelphir Kaltstahl Jan 1 '16 at 13:38
  • 3
    \$\begingroup\$ @Zelphir with encrypting to itself, I meant that the E would never result into an E. That is what this whole challenge is about. \$\endgroup\$ – Adnan Jan 1 '16 at 16:22

24 Answers 24

9
\$\begingroup\$

Pyth, 14 bytes

f!s.eqb@>zTkQ0

I'm not sure if this is Ok but if the input is impossible, nothing is written to stdout and a zero division error is written to stderr. Takes the input on 2 lines, the second one is surrounded by quotes.

Explanation:

               - autoassign z to first input
               - autoassign Q to second input
f            0 - The first value starting from 0 where the output is truthy
   .e       Q  - Enumerate over the second value
        >zT    - z[T:]
       @   k   - The kth item (number in enumeration)
      b        - The character in the enumeration
     q         - Are the two characters equal?
  s            - Sum the values
 !             - Invert them (want first where there isn't a collision)

Try it here!

\$\endgroup\$
55
\$\begingroup\$

JavaScript, 40

(c,p)=>c.search(p.replace(/./g,"[^$&]"))

Using replace, this maps the plaintext input into a regular expression of form /[^H][^E][^L][^L][^O]/ (e.g., for plaintext input HELLO) and then uses search to test for the first index of the ciphertext substring that matches that regex. This regex means "a pattern where the first character is not H, the second character is not E, etc."

$& is a special sequence for replace output that substitutes in the value matched by the first replace argument (in this case, each single character matched by /./).

\$\endgroup\$
  • 16
    \$\begingroup\$ Oh, wow, that's a really clever solution! \$\endgroup\$ – Doorknob Dec 30 '15 at 16:07
  • 2
    \$\begingroup\$ I didn't know about $&! Thanks for teaching my something today. \$\endgroup\$ – ETHproductions Dec 30 '15 at 16:19
  • 1
    \$\begingroup\$ @ETHproductions Me neither, until today! I also learned about $` and $' in the process of researching this answer, which provide "the portion of the string that precedes/follows the matched substring" \$\endgroup\$ – apsillers Dec 30 '15 at 16:22
  • 1
    \$\begingroup\$ Wow, that's awesome! I should read the docs more often ;) \$\endgroup\$ – ETHproductions Dec 30 '15 at 16:24
44
\$\begingroup\$

Turing Machine Simulator - 15660 bytes (Non-Competing)

Can't have an Enigma challenge without turing machine code.

0 * * l 0
0 _ _ l ,
, _ , l 1
1 _ 0 r 2
2 * * r 2
2 , * r 3
3 * * r 3
3 , * r 4
4 * * r 4
4 _ * r 13
4 A a l a'                                                                                                                                                                                                        
4 B b l b'                                                                                                                                                                                                        
4 C c l c'                                                                                                                                                                                                        
4 D d l d'                                                                                                                                                                                                        
4 E e l e'                                                                                                                                                                                                        
4 F f l f'                                                                                                                                                                                                        
4 G g l g'                                                                                                                                                                                                        
4 H h l h'                                                                                                                                                                                                        
4 I i l i'                                                                                                                                                                                                        
4 J j l j'                                                                                                                                                                                                        
4 K k l k'                                                                                                                                                                                                        
4 L l l l'                                                                                                                                                                                                        
4 M m l m'                                                                                                                                                                                                        
4 N n l n'                                                                                                                                                                                                        
4 O o l o'                                                                                                                                                                                                        
4 P p l p'                                                                                                                                                                                                        
4 Q q l q'                                                                                                                                                                                                        
4 R r l r'                                                                                                                                                                                                        
4 S s l s'                                                                                                                                                                                                        
4 T t l t'                                                                                                                                                                                                        
4 U u l u'                                                                                                                                                                                                        
4 V v l v'                                                                                                                                                                                                        
4 W w l w'                                                                                                                                                                                                        
4 X x l x'                                                                                                                                                                                                        
4 Y y l y'                                                                                                                                                                                                        
4 Z z l z'
a' * * l a'
a' , * l a
b' * * l b'
b' , * l b
c' * * l c'
c' , * l c
d' * * l d'
d' , * l d
e' * * l e'
e' , * l e
f' * * l f'
f' , * l f
g' * * l g'
g' , * l g
h' * * l h'
h' , * l h
i' * * l i'
i' , * l i
j' * * l j'
j' , * l j
k' * * l k'
k' , * l k
l' * * l l'
l' , * l l
m' * * l m'
m' , * l m
n' * * l n'
n' , * l n
o' * * l o'
o' , * l o
p' * * l p'
p' , * l p
q' * * l q'
q' , * l q
r' * * l r'
r' , * l r
s' * * l s'
s' , * l s
t' * * l t'
t' , * l t
u' * * l u'
u' , * l u
v' * * l v'
v' , * l v
w' * * l w'
w' , * l w
x' * * l x'
x' , * l x
y' * * l y'
y' , * l y
z' * * l z'
z' , * l z

a * * l a
a _ * r A
a a * r A
a b * r A
a c * r A
a d * r A
a e * r A
a f * r A
a g * r A
a h * r A
a i * r A
a j * r A
a k * r A
a l * r A
a m * r A
a n * r A
a o * r A
a p * r A
a q * r A
a r * r A
a s * r A
a t * r A
a u * r A
a v * r A
a w * r A
a x * r A
a y * r A
a z * r A
b * * l b
b _ * r B
b a * r B
b b * r B
b c * r B
b d * r B
b e * r B
b f * r B
b g * r B
b h * r B
b i * r B
b j * r B
b k * r B
b l * r B
b m * r B
b n * r B
b o * r B
b p * r B
b q * r B
b r * r B
b s * r B
b t * r B
b u * r B
b v * r B
b w * r B
b x * r B
b y * r B
b z * r B
c * * l c
c _ * r C
c a * r C
c b * r C
c c * r C
c d * r C
c e * r C
c f * r C
c g * r C
c h * r C
c i * r C
c j * r C
c k * r C
c l * r C
c m * r C
c n * r C
c o * r C
c p * r C
c q * r C
c r * r C
c s * r C
c t * r C
c u * r C
c v * r C
c w * r C
c x * r C
c y * r C
c z * r C
d * * l d
d _ * r D
d a * r D
d b * r D
d c * r D
d d * r D
d e * r D
d f * r D
d g * r D
d h * r D
d i * r D
d j * r D
d k * r D
d l * r D
d m * r D
d n * r D
d o * r D
d p * r D
d q * r D
d r * r D
d s * r D
d t * r D
d u * r D
d v * r D
d w * r D
d x * r D
d y * r D
d z * r D
e * * l e
e _ * r E
e a * r E
e b * r E
e c * r E
e d * r E
e e * r E
e f * r E
e g * r E
e h * r E
e i * r E
e j * r E
e k * r E
e l * r E
e m * r E
e n * r E
e o * r E
e p * r E
e q * r E
e r * r E
e s * r E
e t * r E
e u * r E
e v * r E
e w * r E
e x * r E
e y * r E
e z * r E
f * * l f
f _ * r F
f a * r F
f b * r F
f c * r F
f d * r F
f e * r F
f f * r F
f g * r F
f h * r F
f i * r F
f j * r F
f k * r F
f l * r F
f m * r F
f n * r F
f o * r F
f p * r F
f q * r F
f r * r F
f s * r F
f t * r F
f u * r F
f v * r F
f w * r F
f x * r F
f y * r F
f z * r F
g * * l g
g _ * r G
g a * r G
g b * r G
g c * r G
g d * r G
g e * r G
g f * r G
g g * r G
g h * r G
g i * r G
g j * r G
g k * r G
g l * r G
g m * r G
g n * r G
g o * r G
g p * r G
g q * r G
g r * r G
g s * r G
g t * r G
g u * r G
g v * r G
g w * r G
g x * r G
g y * r G
g z * r G
h * * l h
h _ * r H
h a * r H
h b * r H
h c * r H
h d * r H
h e * r H
h f * r H
h g * r H
h h * r H
h i * r H
h j * r H
h k * r H
h l * r H
h m * r H
h n * r H
h o * r H
h p * r H
h q * r H
h r * r H
h s * r H
h t * r H
h u * r H
h v * r H
h w * r H
h x * r H
h y * r H
h z * r H
i * * l i
i _ * r I
i a * r I
i b * r I
i c * r I
i d * r I
i e * r I
i f * r I
i g * r I
i h * r I
i i * r I
i j * r I
i k * r I
i l * r I
i m * r I
i n * r I
i o * r I
i p * r I
i q * r I
i r * r I
i s * r I
i t * r I
i u * r I
i v * r I
i w * r I
i x * r I
i y * r I
i z * r I
j * * l j
j _ * r J
j a * r J
j b * r J
j c * r J
j d * r J
j e * r J
j f * r J
j g * r J
j h * r J
j i * r J
j j * r J
j k * r J
j l * r J
j m * r J
j n * r J
j o * r J
j p * r J
j q * r J
j r * r J
j s * r J
j t * r J
j u * r J
j v * r J
j w * r J
j x * r J
j y * r J
j z * r J
k * * l k
k _ * r K
k a * r K
k b * r K
k c * r K
k d * r K
k e * r K
k f * r K
k g * r K
k h * r K
k i * r K
k j * r K
k k * r K
k l * r K
k m * r K
k n * r K
k o * r K
k p * r K
k q * r K
k r * r K
k s * r K
k t * r K
k u * r K
k v * r K
k w * r K
k x * r K
k y * r K
k z * r K
l * * l l
l _ * r L
l a * r L
l b * r L
l c * r L
l d * r L
l e * r L
l f * r L
l g * r L
l h * r L
l i * r L
l j * r L
l k * r L
l l * r L
l m * r L
l n * r L
l o * r L
l p * r L
l q * r L
l r * r L
l s * r L
l t * r L
l u * r L
l v * r L
l w * r L
l x * r L
l y * r L
l z * r L
m * * l m
m _ * r M
m a * r M
m b * r M
m c * r M
m d * r M
m e * r M
m f * r M
m g * r M
m h * r M
m i * r M
m j * r M
m k * r M
m l * r M
m m * r M
m n * r M
m o * r M
m p * r M
m q * r M
m r * r M
m s * r M
m t * r M
m u * r M
m v * r M
m w * r M
m x * r M
m y * r M
m z * r M
n * * l n
n _ * r N
n a * r N
n b * r N
n c * r N
n d * r N
n e * r N
n f * r N
n g * r N
n h * r N
n i * r N
n j * r N
n k * r N
n l * r N
n m * r N
n n * r N
n o * r N
n p * r N
n q * r N
n r * r N
n s * r N
n t * r N
n u * r N
n v * r N
n w * r N
n x * r N
n y * r N
n z * r N
o * * l o
o _ * r O
o a * r O
o b * r O
o c * r O
o d * r O
o e * r O
o f * r O
o g * r O
o h * r O
o i * r O
o j * r O
o k * r O
o l * r O
o m * r O
o n * r O
o o * r O
o p * r O
o q * r O
o r * r O
o s * r O
o t * r O
o u * r O
o v * r O
o w * r O
o x * r O
o y * r O
o z * r O
p * * l p
p _ * r P
p a * r P
p b * r P
p c * r P
p d * r P
p e * r P
p f * r P
p g * r P
p h * r P
p i * r P
p j * r P
p k * r P
p l * r P
p m * r P
p n * r P
p o * r P
p p * r P
p q * r P
p r * r P
p s * r P
p t * r P
p u * r P
p v * r P
p w * r P
p x * r P
p y * r P
p z * r P
q * * l q
q _ * r Q
q a * r Q
q b * r Q
q c * r Q
q d * r Q
q e * r Q
q f * r Q
q g * r Q
q h * r Q
q i * r Q
q j * r Q
q k * r Q
q l * r Q
q m * r Q
q n * r Q
q o * r Q
q p * r Q
q q * r Q
q r * r Q
q s * r Q
q t * r Q
q u * r Q
q v * r Q
q w * r Q
q x * r Q
q y * r Q
q z * r Q
r * * l r
r _ * r R
r a * r R
r b * r R
r c * r R
r d * r R
r e * r R
r f * r R
r g * r R
r h * r R
r i * r R
r j * r R
r k * r R
r l * r R
r m * r R
r n * r R
r o * r R
r p * r R
r q * r R
r r * r R
r s * r R
r t * r R
r u * r R
r v * r R
r w * r R
r x * r R
r y * r R
r z * r R
s * * l s
s _ * r S
s a * r S
s b * r S
s c * r S
s d * r S
s e * r S
s f * r S
s g * r S
s h * r S
s i * r S
s j * r S
s k * r S
s l * r S
s m * r S
s n * r S
s o * r S
s p * r S
s q * r S
s r * r S
s s * r S
s t * r S
s u * r S
s v * r S
s w * r S
s x * r S
s y * r S
s z * r S
t * * l t
t _ * r T
t a * r T
t b * r T
t c * r T
t d * r T
t e * r T
t f * r T
t g * r T
t h * r T
t i * r T
t j * r T
t k * r T
t l * r T
t m * r T
t n * r T
t o * r T
t p * r T
t q * r T
t r * r T
t s * r T
t t * r T
t u * r T
t v * r T
t w * r T
t x * r T
t y * r T
t z * r T
u * * l u
u _ * r U
u a * r U
u b * r U
u c * r U
u d * r U
u e * r U
u f * r U
u g * r U
u h * r U
u i * r U
u j * r U
u k * r U
u l * r U
u m * r U
u n * r U
u o * r U
u p * r U
u q * r U
u r * r U
u s * r U
u t * r U
u u * r U
u v * r U
u w * r U
u x * r U
u y * r U
u z * r U
v * * l v
v _ * r V
v a * r V
v b * r V
v c * r V
v d * r V
v e * r V
v f * r V
v g * r V
v h * r V
v i * r V
v j * r V
v k * r V
v l * r V
v m * r V
v n * r V
v o * r V
v p * r V
v q * r V
v r * r V
v s * r V
v t * r V
v u * r V
v v * r V
v w * r V
v x * r V
v y * r V
v z * r V
w * * l w
w _ * r W
w a * r W
w b * r W
w c * r W
w d * r W
w e * r W
w f * r W
w g * r W
w h * r W
w i * r W
w j * r W
w k * r W
w l * r W
w m * r W
w n * r W
w o * r W
w p * r W
w q * r W
w r * r W
w s * r W
w t * r W
w u * r W
w v * r W
w w * r W
w x * r W
w y * r W
w z * r W
x * * l x
x _ * r X
x a * r X
x b * r X
x c * r X
x d * r X
x e * r X
x f * r X
x g * r X
x h * r X
x i * r X
x j * r X
x k * r X
x l * r X
x m * r X
x n * r X
x o * r X
x p * r X
x q * r X
x r * r X
x s * r X
x t * r X
x u * r X
x v * r X
x w * r X
x x * r X
x y * r X
x z * r X
y * * l y
y _ * r Y
y a * r Y
y b * r Y
y c * r Y
y d * r Y
y e * r Y
y f * r Y
y g * r Y
y h * r Y
y i * r Y
y j * r Y
y k * r Y
y l * r Y
y m * r Y
y n * r Y
y o * r Y
y p * r Y
y q * r Y
y r * r Y
y s * r Y
y t * r Y
y u * r Y
y v * r Y
y w * r Y
y x * r Y
y y * r Y
y z * r Y
z * * l z
z , * r Z
z a * r Z
z b * r Z
z c * r Z
z d * r Z
z e * r Z
z f * r Z
z g * r Z
z h * r Z
z i * r Z
z j * r Z
z k * r Z
z l * r Z
z m * r Z
z n * r Z
z o * r Z
z p * r Z
z q * r Z
z r * r Z
z s * r Z
z t * r Z
z u * r Z
z v * r Z
z w * r Z
z x * r Z
z y * r Z
z z * r Z
A * * * 5
A A * l 6
B * * * 5
B B * l 6
C * * * 5
C C * l 6
D * * * 5
D D * l 6
E * * * 5
E E * l 6
F * * * 5
F F * l 6
G * * * 5
G G * l 6
H * * * 5
H H * l 6
I * * * 5
I I * l 6
J * * * 5
J J * l 6
K * * * 5
K K * l 6
L * * * 5
L L * l 6
M * * * 5
M M * l 6
N * * * 5
N N * l 6
O * * * 5
O O * l 6
P * * * 5
P P * l 6
Q * * * 5
Q Q * l 6
R * * * 5
R R * l 6
S * * * 5
S S * l 6
T * * * 5
T T * l 6
U * * * 5
U U * l 6
V * * * 5
V V * l 6
W * * * 5
W W * l 6
X * * * 5
X X * l 6
Y * * * 5
Y Y * l 6
Z * * * 5
Z Z * l 6
5 , * r 15
5 A a r 7
5 B b r 7
5 C c r 7
5 D d r 7
5 E e r 7
5 F f r 7
5 G g r 7
5 H h r 7
5 I i r 7
5 J j r 7
5 K k r 7
5 L l r 7
5 M m r 7
5 N n r 7
5 O o r 7
5 P p r 7
5 Q q r 7
5 R r r 7
5 S s r 7
5 T t r 7
5 U u r 7
5 V v r 7
5 W w r 7
5 X x r 7
5 Y y r 7
5 Z z r 7
7 * * r 7
7 , * r 4
6 * * l 6
6 _ * r 8
8 * _ r 9
9 * * r 9
9 _ * l 10
9 a A r 9
9 b B r 9
9 c C r 9
9 d D r 9
9 e E r 9
9 f F r 9
9 g G r 9
9 h H r 9
9 i I r 9
9 j J r 9
9 k K r 9
9 l L r 9
9 m M r 9
9 n N r 9
9 o O r 9
9 p P r 9
9 q Q r 9
9 r R r 9
9 s S r 9
9 t T r 9
9 u U r 9
9 v V r 9
9 w W r 9
9 x X r 9
9 y Y r 9
9 z Z r 9
10 * * l 10
10 , * l 11
11 * * l 11
11 , * l 12
12 _ 1 r 2
12 0 1 r 2
12 1 2 r 2
12 2 3 r 2
12 3 4 r 2
12 4 5 r 2
12 5 6 r 2
12 6 7 r 2
12 7 8 r 2
12 8 9 r 2
12 9 0 l 12
13 * _ l 13
13 , _ l 14
14 * _ l 14
14 , _ l halt
15 * * r 15
15 _ * l 16
16 * _ l 16
16 , _ l 17
17 * _ l 17
17 , _ l 18
18 * _ l 18
18 _ x * halt

Test it out here

Brief overview:

  1. Set up a counter on the left
  2. Find first uppercase letter in target and make it lowercase. If all letters are lowercase move to step 5.
  3. Find first uppercase letter in code. If most recent letter matches, move on to step 4. Else make letter lowercase and go back to step 2.
  4. Increment counter, make all letters capital, delete first letter in code. Go back to step 2. If no letters are left in code, return clear tape and print x.
  5. Clear all the tape but the counter.
\$\endgroup\$
  • \$\begingroup\$ Also, when testing, the format of the input should be: code,target (no space) \$\endgroup\$ – KoreanwGlasses Dec 30 '15 at 21:23
  • \$\begingroup\$ How long did it take to make this? \$\endgroup\$ – Adnan Dec 30 '15 at 21:24
  • 18
    \$\begingroup\$ Started my homework at 2:00. Got distracted at 2:15. Started this at 2.20. Posted this at 4:20. So about 2 hours. \$\endgroup\$ – KoreanwGlasses Dec 30 '15 at 21:25
  • 5
    \$\begingroup\$ +1, in PPCGSE, it doesn't have to be competing to be appreciated! \$\endgroup\$ – user15259 Jan 1 '16 at 20:33
  • \$\begingroup\$ 9575 bytes (and the current bytecount in the header is false, there are extraneous spaces and some unnecessarily long state names). \$\endgroup\$ – Erik the Outgolfer Oct 14 '18 at 11:36
8
\$\begingroup\$

SWI-Prolog, 115 bytes

a(S,W,R):-length(S,L),length(W,M),N is L-M,between(0,N,I),\+ (between(0,M,J),K is I+J,nth0(J,W,A),nth0(K,S,A)),R=I.

Usage example: a(`ABCDEFGHIJKL`,`HELLO`,R).. This uses the character codes strings declared with backticks. The answer is unified with R. If no match is found, this outputs false..

Explanation:

a(S,W,R):-
    length(S,L),length(W,M),     
    N is L-M,
    between(0,N,I),             % I is successively unified with an integer between 0 
                                % and the last possible index of the coded message

    \+ (                        % This will only be true if what's inside the parentheses 
                                % cannot be proven to be true

        between(0,M,J),         % J is successively unified with an integer between 0 
                                % and the length of the desired word
        K is I+J,
        nth0(J,W,A),nth0(K,S,A) % Check if one letter is the same in both string at 
                                % the same index
    ),                          % If it the case, then it will be 'true' and thus 
                                % the predicate \+ will be false, meaning we need to
                                % backtrack to try a different value of I

    R=I.                        % If we get here it means it didn't find any matching 
                                % letter for this value of I, which is then the answer.

Try it here

\$\endgroup\$
7
\$\begingroup\$

Ruby, 91 79 bytes

->a,b{[*a.chars.each_cons(b.size)].index{|x|x.zip(b.chars).all?{|y|y.uniq==y}}}

Curse you, Enumerator! Why do I have to convert from string to array to Enumerator to array and waste precious bytes? >:(

->a,b{                  # define lambda
[*                      # convert to array...
  a.chars               # get enumerator from string
  .each_cons(b.size)    # each consecutive group of (b.size) letters
]
.index{|x|              # find index of...
  x.zip(b.chars)        # zip group with second input string
  .all?{|y|             # is the block true for every element?
    y.uniq==y           # uniqueify results in same array (no dups)
}}}
\$\endgroup\$
  • \$\begingroup\$ Using [*...] as a golfy alternative to #to_a is a nice touch. \$\endgroup\$ – Wayne Conrad Dec 30 '15 at 19:55
7
\$\begingroup\$

CJam, 17 16 bytes

ll:A,ew{A.=:+!}#

Try it here.

Thanks to @PeterTaylor for saving a byte.

Explanation:

ll:A,ew    e# Finds every slice in the coded message with the length of the word
{A.=:+     e# Compare the characters in each slice to the characters in the word, and add up the result. If the sum is zero, then the slice and the word have no characters in common.
!}#        e# Invert truthiness (0 -> 1, non-0 -> 0) Return index of first truthy value.
\$\endgroup\$
  • \$\begingroup\$ array block # can save you a char: ll:A,ew{A.=:+!}# \$\endgroup\$ – Peter Taylor Dec 30 '15 at 18:33
  • \$\begingroup\$ Amazing how far CJam can be golfed in almost every task... :-o \$\endgroup\$ – agtoever Dec 30 '15 at 19:35
  • \$\begingroup\$ @agtoever I wouldn't say it's really golfing, because 17 bytes was my very first try. The key feature is ew (make slices), everything else just follows. \$\endgroup\$ – geokavel Dec 30 '15 at 19:41
6
\$\begingroup\$

MATL, 27 bytes

jYbZ)tnb!wlhYCw!=a~ftn?1)1-

Examples

>> matl jYbZ)tnb!wlhYCw!=a~ftn?1)1-
> EEEEEEEEEEEE, HELLO

>> matl jYbZ)tnb!wlhYCw!=a~ftn?1)1-
> XEEFSLBSELDJMADNADKDPSSPRNEBWIENPF, DEUTSCHLAND
11

Explanation

j           % input string
YbZ)        % split into two strings based on space. Trailing comma is not a problem
tnb!wlhYC   % arrange first string into sliding columns of the size of the second
w!=         % compare with transposed second string, element-wise with broadcast
a~          % detect columns where all values are 0 (meaning unequal characters)
f           % find indices of such columns
tn?         % if there's at least one such column
1)1-        % pick index of the first and subtract 1 for 0-based indexing
\$\endgroup\$
4
\$\begingroup\$

Haskell, 72 bytes

l=length
h i w s|l s<l w= -1|and$zipWith(/=)w s=i|1<2=h(i+1)w$tail s
h 0

Usage: h 0 "DEUTSCHLAND" "XEEFSLBSELDJMADNADKDPSSPRNEBWIENPF" -> 11.

Simple recursive approach: if the word wcan be placed at the beginning of the string s, return the index counter i, else repeat with i incremented and the tail of s. Stop and return -1 if the length of s is less than the length of w.

\$\endgroup\$
4
\$\begingroup\$

Python 2.7, 111 characters

Tries all starting positions (a) and checks of any of the letters match (using the list comprehension). It returns "None" (Python's "NULL") if nothing is found (the for loop end and nothing is returned, which defaults to "None".

def d(c,s):
 for a in range(len(c)):
  if a not in [((c+s)[a+i:]).index(l)+a for i,l in enumerate(s)]:
   return a

Testsuite:

cases = {
         ("BHGEFXWFTIUPITHHLPETTTCLOEWOELM","WETTERBERICHT"):13,
         ("ABCDEFGHIJKL","HELLO"):0,
         ("EEEEEEEEEEEE","HELLO"):-1,
         ("XEEFSLBSELDJMADNADKDPSSPRNEBWIENPF","DEUTSCHLAND"):11
        }

for idx,(code,string) in enumerate(cases):
    output=d(code,string)
    print "Case: {}: d({:<35},{:<16}) gives: {}. Correct answer is: {}.".format(idx+1,code,string,output,cases[(code,string)])
\$\endgroup\$
  • \$\begingroup\$ You actually have 114 bytes, not 111. Here is a 106-byte version: def d(c,s): for a in range(len(c)): if a not in[a+(c+s)[a+i:].index(l)for i,l in enumerate(s)]:return a \$\endgroup\$ – movatica Apr 28 at 9:29
4
\$\begingroup\$

Brachylog, 48 bytes

[S:W]hlL,WlM,L-M=:0reI,'(0:MeJ+I=:SrmA,W:JmA),I.

This is a direct translation of my Prolog answer. The brachylog_main/2 generated predicate expects a list of two character codes strings with the coded string first as input, and returns the index as output, e.g. brachylog_main([`ABCDEFGHIJKL`,`HELLO`],R)..

Explanation

[S:W]                                            § Unify the input with the list [S,W]

     hlL,WlM,                                    § L and M are the length of S and W

             L-M=:0reI,                          § Enumerate integers between 0 and the 
                                                 § last possible index

                       '(                   ),I. § Unify the output with the current 
                                                 § enumerated integer if what's inside the 
                                                 § parenthesis cannot be proven to be true

                         0:MeJ                   § Enumerate integers between 0 and the
                                                 § length of the word desired

                              +I=:SrmA,W:JmA     § Check if both strings contain at matching
                                                 § indexes the same letter (unified with A)
\$\endgroup\$
3
\$\begingroup\$

Japt, 12 bytes (non-competitive)

UàVr'."[^$&]

I'm gonna need some help with this one.

\$\endgroup\$
  • \$\begingroup\$ Uhhh... Japt doesn't have .search? facepalm \$\endgroup\$ – ETHproductions Jan 1 '16 at 20:25
  • \$\begingroup\$ This can now be done with UàVr'."[^$&] for 12. \$\endgroup\$ – ETHproductions Jan 12 '16 at 4:06
  • \$\begingroup\$ Cool, we're winning now! \$\endgroup\$ – Mama Fun Roll Jan 12 '16 at 4:12
  • \$\begingroup\$ Since the latest revision of this answer uses functionality that postdates the question, I'm marking it as non-competitive. \$\endgroup\$ – Mego Jan 12 '16 at 4:55
  • \$\begingroup\$ Oh forgot about that :P Thanks! \$\endgroup\$ – Mama Fun Roll Jan 12 '16 at 5:00
2
\$\begingroup\$

PHP – 155 bytes

<?php for($p=$argv[1],$q=$argv[2],$l=strlen($q),$i=0,$r=-1;$i<strlen($p)-$l;$i++)if(levenshtein($q,substr($p,$i,$l),2,1,2)==$l){$r=$i;break;}echo$r."\n";

Save as crack.php and run with the arguments in the command line. E.g.:

$ php crack.php BHGEFXWFTIUPITHHLPETTTCLOEWOELM WETTERBERICHT
13
\$\endgroup\$
  • \$\begingroup\$ You can save 25 bytes and golf it down to 130 bytes: for($r=-1;$i<strlen($p=$argv[1])-$l=strlen($q=$argv[2]);$i++)if(levenshtein($q,substr($p,$i,$l),2,1,2)==$l&&$r=$i)break;echo"$r↵"; \$\endgroup\$ – insertusernamehere Dec 30 '15 at 19:03
  • \$\begingroup\$ @insertusernamehere - Wow, that's impressive! So much so that I wouldn't feel right using it! I thought I was being clever using levenshtein, but probably a straightforward iteration within an iteration could do it in fewer bytes. \$\endgroup\$ – user15259 Jan 1 '16 at 20:30
2
\$\begingroup\$

JavaScript, 129 121 118 119* 118 bytes

(w,t){for(j=0;(x=t.length)<(y=w.length);t=' '+t,j++){for(a=i=0;++i<y;)w[i]==t[i]?a=1:a;if(!a)break}return x==y?-1:j}

w is the coded message, t is the test string. This doesn't use regexes, but just compares letter by letter, shifting the test string (i.e. "WETTERBERICHT") by appending space before it. Easy and boring.


* test case with no match didn't work, now it does

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

𝔼𝕊𝕄𝕚𝕟, 14 chars / 25 bytes

îĊⱮ(í,↪`⁅⦃$}]`

Try it here (Firefox only).

Kudos to @apsillers for the idea.

Explanation

               // implicit: î = input1, í = input2
îĊ             // search for first occurrence of:
  Ɱ(í,↪`⁅⦃$}]` // regex created by wrapping each word in [^ and ] (negation matches)
\$\endgroup\$
  • \$\begingroup\$ Whoever downvoted this, is there a reason why? \$\endgroup\$ – Mama Fun Roll Dec 31 '15 at 18:32
2
\$\begingroup\$

TeaScript, 14 bytes 20

xc(yl#`[^${l}]

Similar to @aspillers clever JavaScript solution.

Non-competing because this uses features made after this contest.

Explanation

             // Implicit: x = 1st input, y = 2nd input
x            // First input
 c           // returns index of regex match
 yl#         // Loop through every char in `y`
    `[^${l}] // Replace template, ${l} because current char in `y`
\$\endgroup\$
  • \$\begingroup\$ Does $& not work in place of ${l}? \$\endgroup\$ – ETHproductions Jan 1 '16 at 20:30
  • \$\begingroup\$ @ETHproductions not in this case because I'm using a loop rather than a replace \$\endgroup\$ – Downgoat Jan 1 '16 at 20:55
2
\$\begingroup\$

Ruby, 43 36 bytes

edit: String interpolation inside string interpolation inside a regex, yikes.

The lazy approach: translates the word to a "negative" regex -- The =~ operator does the rest.

->m,w{m=~/#{"[^#{w.chars*'][^'}]"}/}

Test:

f=->m,w{m=~/#{"[^#{w.chars*'][^'}]"}/}

require "minitest/autorun"

describe :f do
  it "works for the given test cases" do
    assert_equal 13, f["BHGEFXWFTIUPITHHLPETTTCLOEWOELM", "WETTERBERICHT"]
    assert_equal 0, f["ABCDEFGHIJKL", "HELLO"]
    assert_equal nil, f["EEEEEEEEEEEE", "HELLO"]
    assert_equal 11, f["XEEFSLBSELDJMADNADKDPSSPRNEBWIENPF", "DEUTSCHLAND"]
    assert_equal nil, f["HKKH", "JJJJJ"]
  end
end
\$\endgroup\$
2
\$\begingroup\$

Python 3, 79 bytes

lambda x,y:[sum(map(str.__eq__,x[i:],y))for i in range(len(x)-len(y))].index(0)

Try it online!

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

05AB1E, 14 bytes

ŒIgùDʒø€Ëà_}нk

Try it online or verify all test cases.

Explanation:

Π              # Get all substrings of the first (implicit) input
 Ig             # Get the length of the second input
   ù            # Only leave the substrings of that length
    D           # Duplicate the list of remaining substrings
     ʒ          # Filter the copy by:
      ø         #  Zip/transpose; swapping rows/columns the current substring with
                #  the second (implicit) input
       €Ë       #  Check for each if both characters are equal (1 if truthy; 0 if falsey)
         à      #  Get the maximum (basically equal to an `any` builtin)
          ≠     #  And invert the boolean (!= 1)
           }н   # After the filter: only leave the first substring
             k  # And get its index in the duplicated list (-1 if none are found)
                # (which is output implicitly as result)
\$\endgroup\$
  • 2
    \$\begingroup\$ Dude, this was totally supposed to be @Emigna's answer ;). I wanted to come here and make a joke about him answering an adnan-question with almost-his-name in it. +1 (Noticed you answered 4 years after-the-fact after I posted this after-the-fact comment). \$\endgroup\$ – Magic Octopus Urn Apr 29 at 21:31
  • \$\begingroup\$ @MagicOctopusUrn When I saw the challenge I thought the same thing, but @Emigna usually answers new answers and doesn't look that often at existing answers. So since this one didn't had any 05AB1E answers I figured I'd add one. You're indeed right that @Emigna would have been best suited to answer this challenge. ;p \$\endgroup\$ – Kevin Cruijssen Apr 30 at 6:12
1
\$\begingroup\$

Jolf, 14 bytes

Try it here!

 siρI".'[^$&]
_s            search
  i            input 1 for
    I          input 2
   ρ            replacing (2 byte rho character)
     ".'         all characters
        [^$&]    with that
\$\endgroup\$
1
\$\begingroup\$

Perl, 38 + 1 = 39 bytes

perl -E "$r=<>=~s!.![^$&]!gr;say@-if<>=~/$r/x" < input

where input looks like:

WETTERBERICHT
BHGEFXWFTIUPITHHLPETTTCLOEWOELMRXXPAKAXMAMTXXUDLTWTNHKELEPPLHPRQ

This is the same idea as the javascript one.

\$\endgroup\$
  • \$\begingroup\$ The 'x' is unnecessary \$\endgroup\$ – Zaid Jan 2 '16 at 8:37
1
\$\begingroup\$

Java, 136 Characters

Regex-based solution inspired by apsillers JavaScript version.

class L{public static void main(String[]a){a=a[0].split(a[1].replaceAll("(.)","[^$1]"));System.out.print(a.length>1?a[0].length():-1);}}
\$\endgroup\$
1
\$\begingroup\$

Brachylog (v2), 16 bytes

bʰ↙.Pz₁≠ᵐzhc~hP∧

Try it online!

Brachylog is usually very good at failing when solving something is impossible.

This is not one of those times.

(takes input as a list [message, word]. The header prints it all very prettily but the output of the actual predicate is just a number if it succeeds)

                    The input
b                   with a number of letters removed from the beginning
 ʰ                  of its first element
  ↙.                where that number is the output
    P               is P
     z₁             which with its elements zipped, without cycling
       ≠ᵐ           contains no duplicate pairs
         z          and which zipped back
          h         has a first element
           c        which concatenated
            ~h      is the first element of
              P     P
               ∧    (which is not the output).

bʰ↙.Plᵐ≥₁∧Pz₁≠ᵐ∧ seems to work just as well for the same byte count.

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

C++ (gcc), 160 153 150 bytes

#include<map>
int f(std::string c,std::string w){int i=-1,k,e=1;while(e&&w.size()+i++<c.size())for(e=k=0;k<w.size();)e+=c[i+k]==w[k++];return e?-1:i;}

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ @ceilingcat: you can do 157 bytes The code fails for two testcases though (as does my original one). I fixed it for a few extra bytes. \$\endgroup\$ – movatica Apr 29 at 21:02
  • 1
    \$\begingroup\$ Plus, your initialization of k in the outer loop introduced another bug, where with each iteration, one less character was compared. \$\endgroup\$ – movatica Apr 29 at 21:08
  • \$\begingroup\$ Turns out, it's even shorter without goto and without all the bugs... \$\endgroup\$ – movatica Apr 29 at 21:30
0
\$\begingroup\$

Perl 5, 46 bytes

Uses @apsillers' regex idea.

$a=<>=~s/./[^$&]/gr;/$a/g;$_=(length$a)/-4+pos

Try it online!

\$\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.