Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Telephone keyboard input recognition

Name: Anonymous 2008-02-27 10:58

from http://www.ieee.org/web/membership/students/scholarshipsawardscontests/xtremesamples.html

Can you do it /prog/? Here's the task:


 On a standard telephone, the numbers 1-9 can be used to correspond to a set of letters:

1: space            2: ABC     3: DEF       4: GHI               5: JKL       6: MNO

7: PQRS           8: TUV      9: WXYZ

Using the keypad, you can 'spell' words by entering the digits that correspond to each letter of the word. For example, 'words' is spelled 96737.

For this problem, we are given a dictionary file called with no more than 100,000 words, one per line, sorted in alphabetical order. Each word is comprised of no more than 18 characters, all lowercase letters from the phone keypad. Here is a (very short!) example of a dictionary file we will use in the examples:

Your program should read a string of digits (from 2 to 9, not using 1 as space) from the console and find the words in the dictionary whose spellings contain that series of consecutive digits anywhere within the word.

• If there are no matches, print the string 'No matches'
• If there is one match, print the matching word.
• If there are n>1 matches, print the string 'n matches:' followed by the matching

words, one per line.

NOTE: To make it easier to read the examples below, these are the 'spellings' of the words in words.txt, in digits:

cappuccino: 2277822466
chocolate: 246265283
cinnamon: 24662666
coffee: 263333
latte: 52883
vanilla: 8264554

examples

 contents of words.txt:

cappuccino
chocolate
cinnamon
coffee
latte
vanilla

program words.txt 22222
No matches

program words.txt 3333
coffee

program words.txt 626
2 matches:

chocolate
cinnamon


**NOTE**
obviously this is just for fun, OP (me) doesn't profit from your lisp solutions nor it's homework. It's from 2006 anyway.

I'm curious if you fags here can do it. some can, im sure.
I'll post my solution once I see a solution or two posted.

Name: Anonymous 2008-02-27 11:02

Tree.

Name: Anonymous 2008-02-27 11:17


(define (search c)
  (define phone-list
    '((1 . " ")
    (2 . "abc")
    (3 . "def")
    (4 . "hgi")
    (5 . "jkl")
    (6 . "mno")
    (7 . "pqrs")
    (8 . "tuv")
    (9 . "wxyz")))
  (define (iter c l)
    (if (null? l) '()
    (if (member c (string->list (cdar l)))
        (caar l) (iter c (cdr l)))))
  (iter c phone-list))

(define (phonify str)
  (map search (string->list str)))

Name: Anonymous 2008-02-27 11:17

Hash Table.

Name: Anonymous 2008-02-27 11:30

where's my words.txt

Name: Anonymous 2008-02-27 12:04

>>1-5
Same person and we have been trolled constantly.

Name: Anonymous 2008-02-27 12:34

haha, I remember this. I think I converted words.txt to all digits and then used a hash table.

Name: Anonymous 2008-02-27 12:58

XTREME

Name: Anonymous 2008-02-27 13:03

#!/usr/bin/env python

KEYS = {}
for i, k in enumerate(
    (' ',    'abc', 'def',
     'ghi',  'jkl', 'mno',
     'pqrs', 'tuv', 'wxyz')):
    for c in k: KEYS[c] = str(i+1)

if __name__ == '__main__':
    from sys import argv

    wordlist = dict((''.join(KEYS[c] for c in word), word)
                    for word in open(argv[1]).read().split('\n'))
    match = [w for (n, w) in wordlist.iteritems() if argv[2] in n]

    if match:
        if len(match) > 1:
            print len(match), 'matches'
        for w in match:
            print w
    else:
        print 'No matches'

Name: Anonymous 2008-02-27 13:16

>>9
Takes no less then a minute to find 223355 on the 1,000,000 word file.

Name: Anonymous 2008-02-27 13:30

>>10
Doesn't change the fact that it's the first actual solution in the thread.

Name: Anonymous 2008-02-27 13:36

import Data.Char (ord, digitToInt)
import Data.List (isInfixOf)
import System (getArgs)
import Data.Array

keypad = zip [2 .. 9] ["abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"]

spell = map ((table !) . ord)
    where table = listArray (ord 'a', ord 'z') (inverseLookup keypad)
          inverseLookup =  concatMap (\(x, ys) -> replicate (length ys) x)

findSpelling query = filter (isInfixOf query . spell)
                          
main = do [f, s] <- getArgs
          contents <- readFile f
          putStrLn $ case findSpelling (map digitToInt s) (lines contents) of
                       [] -> "No matches"
                       [x] -> x
                       xs -> show (length xs) ++ " matches:\n" ++ concatMap ("\n" ++) xs

Name: Anonymous 2008-02-27 13:46

I'm curious if you fags here can do it. some can, im sure.

I'm curious if there's actually a /prog/ regular who couldn't do it.

Name: Anonymous 2008-02-27 14:03

S=626 cat words.txt | tr 'a-z' '22233344455566677778889999' | paste words.txt - | grep $S | cut -f1

Name: Anonymous 2008-02-27 14:09

>>13
I'm pretty sure there are a few /prog/ regulars who can't even program.

Name: Anonymous 2008-02-27 14:12

>>15
Yeah, there's a lot of Java threads.

Name: Anonymous 2008-02-27 14:23

What the fuck? They are giving 24 hours for the solutions of these, I thought it would be something more difficult (faggot to be participant of the 2008 challenge)

Name: Anonymous 2008-02-27 14:28

>>17
perhaps they give you like 20 problems to solve in that time

Name: Anonymous 2008-02-27 14:34

Languages supported are:   C/C++ (using gcc), Java (using Sun’s JDK) and C# (using Mono)

fuck that shit. we should be able to use any programming language available, including shell scripts. but at least they still allow C.

>>18
Bonus points for writing all solutions in x86 asm.

Name: Anonymous 2008-02-27 14:39


#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

typedef struct wmatch wmatch_t;

struct wmatch
{
    char     *word;
    wmatch_t *next;
};


#define WORDMAP_SIZE 25
const char wordmap[WORDMAP_SIZE] =
{
                    '2', '2', '2',  '3', '3', '3',
    '4', '4', '4',  '5', '5', '5',  '6', '6', '6',
    '7', '7', '7',  '8', '8', '8',  '9', '9', '9', '9'
};


char *strdup(const char *str)
{
    char *r; {const char *p;
    for(p=str; *p; p++);
    if (!(r=malloc(p - str + 1))) return NULL;}
    {char *p;
    for(p=r; *str; p++, str++) {*p=*str;}
    *p=0;}
    return r;
}


char wordtonum(const char w)
{
    register int p = w - 'a';

    if (p >= 0 && p <= WORDMAP_SIZE)
    {
        return wordmap[p];
    }

    return 0;
}


void strtonum(const char *word)
{
    for(; *word; word++)
    {
        putchar(wordtonum(*word));
    }

    putchar('\n');
}


int num_contain(const char *word, const char *num)
{
    for(; *word; *word++)
    {
        const char *w=word, *n=num;

        for(;; w++, n++)
        {
            if (!*n) { return 0; }
            if (!*w) { return -1; } // word ends before num does
            if (wordtonum(*w) != *n) { break; }
        }
    }

    return -1;
}


int main(int argc, char **argv)
{
    FILE *fp;
    char *p;
    char readbuf[1024];
    wmatch_t *m = NULL, *c = NULL;
    unsigned long mc = 0;

    if (argc < 2)
    {
        fprintf(stderr, "Usage: %s <number>\n", argc < 1 ? "(phone)" : argv[0]);
        return -1;
    }

    p = argv[1];

    for(; *p; p++)
    {
        if (*p <= '1' || *p > '9')
        {
            fprintf(stderr, "Number `%s' is invalid.\n", argv[1]);
            return -1;
        }
    }

    if (!(fp = fopen("words.txt", "r")))
    {
        perror("Error opening `words.txt'");
        return -1;
    }

    while(fgets(readbuf, sizeof(readbuf), fp))
    {
        if (num_contain(readbuf, argv[1]) == 0)
        {
            if (!m)
            {
                c = m = malloc(sizeof(wmatch_t));
            }
            else
            {
                c->next = malloc(sizeof(wmatch_t));
                c = c->next;
            }

            c->word = strdup(readbuf);
            c->next = NULL;
            mc++;
        }
    }

    fclose(fp);

    if (!mc)
    {
        puts("No matches");
        return 0;
    }

    if (mc > 1)
    {
        printf("%lu matches:\n\n", mc);
    }

    for(c = m; c; c = c->next)
    {
        printf("%s", c->word);
    }

    return 0;
}

Name: Anonymous 2008-02-27 14:42

>>18
I think they would need more than 20 to saturate an EXPERT PROGRAMMER

but well, I was going to take a drivers license test some time in the duration of this anyway.

Name: Anonymous 2008-02-27 14:57

vanilla: 8264554
O RLY?

#!/bin/perl
use feature "say";
open WORDS, '<', shift or die;
$_ = pop or die;
die if /[^2-9]/;
s/2/[abc]/g;
s/3/[def]/g;
s/4/[ghi]/g;
s/5/[jkl]/g;
s/6/[mno]/g;
s/7/[pqrs]/g;
s/8/[tuv]/g;
s/9/[wxyz]/g;
$r = $_;
$num = @found = grep /$r/o, <WORDS>;
say "No matches" unless $num;
say "$num matches:\n" if $num > 1;
say @found;

Name: Anonymous 2008-02-27 15:03

Might have some bugs, but wrote this in around 5 minutes.

#include <stdio.h>

char words[1800000];
char wordt[1800000];
main(int argc, char **argv) {
 FILE *i = fopen(argv[1],"rb");
 int j=0;
 char *s;
 for(;;) {
  switch(wordt[j]=fgetc(i)) {
   case 'a': case 'b': case 'c':
    words[j++] = '2';
    break;
   case 'd': case 'e': case 'f':
    words[j++] = '3';
    break;
   case 'g': case 'h': case 'i':
    words[j++] = '4';
    break;
   case 'j': case 'k': case 'l':
    words[j++] = '5';
    break;
   case 'm': case 'n': case 'o':
    words[j++] = '6';
    break;
   case 'p': case 'q': case 'r': case 's':
    words[j++] = '7';
    break;
   case 't': case 'u': case 'v':
    words[j++] = '8';
    break;
   case 'w': case 'x': case 'y': case 'z':
    words[j++] = '9';
    break;
   case EOF:
    fclose(i);
    words[j] = 0;
    goto done_1;
   case '\n':
    while(j%18) {
     words[j]= wordt[j] = ' ';
     j++;
    }
  }
 }
 done_1:
 s = &words;
 while(s=strstr(s,argv[2])) {
  int a = (s-words / 18)*18;
  while((a+1)%18)
   putchar(wordt[a++]);
  putchar('\n');
 }
}

Name: Anonymous 2008-02-27 15:07

>>23
that looks suspiciously like an example from K&R

Name: Anonymous 2008-02-27 15:43

>>23
that looks suspiciously like utter crap

Name: Anonymous 2008-02-27 16:17

>>24-25
You have been caught being trolled.

Name: Anonymous 2008-02-27 16:20

Might have some bugs, but wrote this in around 5 minutes.

#include <stdio.h>

int main(void)
{
    printf("hello, world\n");
    return 0;
}

Name: Anonymous 2008-02-27 16:57

Might have some bugs, but wrote this in around 5 minutes.
int main (int argc, char **argv) {
 while (1)
  fork();
 return 0;
}

Name: Anonymous 2008-02-27 17:13

Might have some bugs, but wrote this in around 5 minutes.
[code]
int main (int argc, char **argv){
    while(1){
      CreateProcess((DWORD)NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, (DWORD)NULL, (u_int)NULL, "notepad.exe", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
}
return NULL;
}

Name: Anonymous 2008-02-27 17:17

Name: Anonymous 2008-02-27 17:30

>>24-25
Guess what?
YHBT
oaer
uveo
 enl
   l
   e
   d

Name: Anonymous 2008-02-27 22:32

Any solution that makes a big string of enumerated digit sequences for each word and searches that string for the digit sequence is wrong. Clever, but wrong. Think about it.


(defvar *num-char-map* '("" " " "ABC" "DEF" "GHI" "JKL" "MNO" "PQRS" "TUV" "WXYZ"))

(defun num-string-match (num-str sample-str mapping)
  (let ((nl (length num-str))
        (sl (length sample-str)))
    (cond ((= 0 nl) t)
          ((> nl sl) nil)
          (t (let ((nc (subseq num-str 0 1))
                   (sc (string-upcase (subseq sample-str 0 1)))
                   (sr (subseq sample-str 1)))
               (let ((pos (position-if #'(lambda (str)
                                           (find (aref sc 0) str))
                                       mapping)))
                 (or (and pos
                          (= (parse-integer nc) pos)
                          (num-string-match (subseq num-str 1) sr mapping))
                     (num-string-match num-str sr mapping))))))))

(defun num-match-words (num-str words &optional (mapping *num-char-map*))
  (remove-if-not #'(lambda (w)
                     (num-string-match num-str w mapping))
                 words))

(defun read-words-file (word-file)
  (with-open-file (f word-file)
    (let ((words nil))
     (do ((l (read-line f nil :eof) (read-line f nil :eof)))
         ((eql l :eof) (nreverse words))
       (push l words)))))

(defun num-match-file (num-str word-file)
  (num-match-words num-str (read-words-file word-file)))

(defun telekey (file num)
  (let* ((words (num-match-file num file))
         (wordlen (length words)))
    (cond ((= 0 wordlen) (format t "No matches~%"))
          ((/= 1 wordlen) (format t "~d matches:~%~%" wordlen)))
    (dolist (w words)
      (format t "~a~%" w))))

Name: Anonymous 2008-02-27 23:06

VANILLA 8264554 ISNT
VANILLA 8264554 ISNT
VANILLA 8264554 ISNT
VANILLA 8264554 ISNT

WTF?

Name: Anonymous 2008-02-27 23:23

>>33
Let me introduce you to >>22

Name: Anonymous 2008-02-28 0:41

vanilli

Name: Anonymous 2008-02-28 2:25

>>32
explain.

Name: Anonymous 2008-02-28 2:38

>>36
It's beyond you.

Name: Anonymous 2008-02-28 3:52

I think this problem is NP-complete

Name: Anonymous 2008-02-28 4:30


ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ
ØØ      ØØ   ØØØØ   ØØ       ØØØ      ØØØ       ØØØØ       ØØ
ØØ   ØØØØØØ   ØØ   ØØØ   ØØ   ØØ   ØØØØØØ   ØØ   ØØØØØ   ØØØØ
ØØ   ØØØØØØØ      ØØØØ   ØØ   ØØ   ØØØØØØ   ØØ   ØØØØØ   ØØØØ
ØØ      ØØØØØ    ØØØØØ       ØØØ      ØØØ       ØØØØØØ   ØØØØ
ØØ   ØØØØØØØ      ØØØØ   ØØØØØØØ   ØØØØØØ   Ø   ØØØØØØ   ØØØØ
ØØ   ØØØØØØ   ØØ   ØØØ   ØØØØØØØ   ØØØØØØ   ØØ   ØØØØØ   ØØØØ
ØØ      ØØ   ØØØØ   ØØ   ØØØØØØØ      ØØØ   ØØØ   ØØØØ   ØØØØ
ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ

Name: Anonymous 2008-02-28 7:02

Haha, where are haskellfags now?

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List