title: Build an English word syllable counter

text:
# Question
Title: Build an English word syllable counter
Write a program or function to estimate as closely as possible the number of syllables in English words.

The input list is here: 1000 basic English words. There are only 997 words because a few duplicates were removed.

For each word, output a line containing the word, a comma (`,`), and the number of syllables and no other characters except for new-line, e.g. `photograph,3` (pho-to-graph). Use the code snippet below to score your answer. Paste your code and output into the respective boxes and press the "Submit" button.

### Scoring

All scoring is calculated automatically by the snippet, but here is how it works in order to lower your score:

* 60 points for each byte, however if you don't use any Unicode codepoints above U+00FF the snippet will calculate characters instead of bytes
* Each word where the number of syllables is correct will score 0

Scoring table for wrong syllables. The axes are symmetrical, one is the number of wrong syllables per word, and the other is the number of words with that number of syllables wrong:

```
 | 1| 2| 3| 4| …
-+--+--+--+--+--
1| 1| 3| 6|10|
-+--+--+--+--+--
2| 3| 9|18|30|
-+--+--+--+--+--
3| 6|18|36|60|
-+--+--+--+--+--
4|10|30|60|100
-+--+--+--+--+--
…|  |  |  |  |

```
* If you have 200 words with 1 wrong syllable and 100 words with 2 wrong syllables your score for wrong syllables will be `200*201/2 * 1*2/2 + 100*101/2 * 2*3/2` = `20100 * 1 + 5050 * 3` = `20100 + 15150` = `35250`
* The scoring is designed to make it easy to lower your score when you have a lot of wrong syllables but hard when you only have a few
* Duplicate words in your output will **not** be removed. Outputting `photograph,1`, `photograph,2`, `photograph,3` will simply increase your score
* Post all three scores, Code, Word and Total. The Total Score will be used to determine a winner

You can use the code snippet to see how many syllables are expected for each word. Simply run it with no input and it will output the list in the expected format, as well as all the words where the number of syllables is wrong, e.g. `photograph *1, (3)`.

```
var syl = {
  "a": 1,
  "about": 2,
  "above": 2,
  "across": 2,
  "act": 1,
  "active": 2,
  "activity": 4,
  "add": 1,
  "afraid": 2,
  "after": 2,
  "again": 2,
  "age": 1,
  "ago": 2,
  "agree": 2,
  "air": 1,
  "all": 1,
  "alone": 2,
  "along": 2,
  "already": 3,
  "always": 2,
  "am": 1,
  "amount": 2,
  "an": 1,
  "and": 1,
  "angry": 2,
  "another": 3,
  "answer": 2,
  "any": 2,
  "anyone": 3,
  "anything": 3,
  "anytime": 3,
  "appear": 3,
  "apple": 2,
  "are": 1,
  "area": 3,
  "arm": 1,
  "army": 2,
  "around": 2,
  "arrive": 2,
  "art": 1,
  "as": 1,
  "ask": 1,
  "at": 1,
  "attack": 2,
  "aunt": 1,
  "autumn": 2,
  "away": 2,
  "baby": 2,
  "back": 1,
  "bad": 1,
  "bag": 1,
  "ball": 1,
  "bank": 1,
  "base": 1,
  "basket": 2,
  "bath": 1,
  "be": 1,
  "bean": 1,
  "bear": 1,
  "beautiful": 3,
  "bed": 1,
  "bedroom": 2,
  "beer": 2,
  "before": 2,
  "begin": 2,
  "behave": 2,
  "behind": 2,
  "bell": 1,
  "below": 2,
  "besides": 2,
  "best": 1,
  "better": 2,
  "between": 2,
  "big": 1,
  "bird": 1,
  "birth": 1,
  "birthday": 2,
  "bit": 1,
  "bite": 1,
  "black": 1,
  "bleed": 1,
  "block": 1,
  "blood": 1,
  "blow": 1,
  "blue": 1,
  "board": 1,
  "boat": 1,
  "body": 2,
  "boil": 2,
  "bone": 1,
  "book": 1,
  "border": 2,
  "born": 1,
  "borrow": 2,
  "both": 1,
  "bottle": 2,
  "bottom": 2,
  "bowl": 1,
  "box": 1,
  "boy": 1,
  "branch": 1,
  "brave": 1,
  "bread": 1,
  "break": 1,
  "breakfast": 2,
  "breathe": 1,
  "bridge": 1,
  "bright": 1,
  "bring": 1,
  "brother": 2,
  "brown": 1,
  "brush": 1,
  "build": 1,
  "burn": 1,
  "bus": 1,
  "business": 2,
  "busy": 2,
  "but": 1,
  "buy": 1,
  "by": 1,
  "cake": 1,
  "call": 1,
  "can": 1,
  "candle": 2,
  "cap": 1,
  "car": 1,
  "card": 1,
  "care": 1,
  "careful": 2,
  "careless": 2,
  "carry": 2,
  "case": 1,
  "cat": 1,
  "catch": 1,
  "central": 2,
  "century": 3,
  "certain": 2,
  "chair": 1,
  "chance": 1,
  "change": 1,
  "chase": 1,
  "cheap": 1,
  "cheese": 1,
  "chicken": 2,
  "child": 1,
  "children": 2,
  "chocolate": 2,
  "choice": 1,
  "choose": 1,
  "circle": 2,
  "city": 2,
  "class": 1,
  "clean": 1,
  "clear": 2,
  "clever": 2,
  "climb": 1,
  "clock": 1,
  "close": 1,
  "cloth": 1,
  "clothes": 1,
  "cloud": 1,
  "cloudy": 2,
  "coat": 1,
  "coffee": 2,
  "coin": 1,
  "cold": 1,
  "collect": 2,
  "colour": 2,
  "comb": 1,
  "come": 1,
  "comfortable": 3,
  "common": 2,
  "compare": 2,
  "complete": 2,
  "computer": 3,
  "condition": 3,
  "contain": 2,
  "continue": 3,
  "control": 2,
  "cook": 1,
  "cool": 1,
  "copper": 2,
  "corn": 1,
  "corner": 2,
  "correct": 2,
  "cost": 1,
  "count": 1,
  "country": 2,
  "course": 1,
  "cover": 2,
  "crash": 1,
  "cross": 1,
  "cry": 1,
  "cup": 1,
  "cupboard": 2,
  "cut": 1,
  "dance": 1,
  "dangerous": 3,
  "dark": 1,
  "daughter": 2,
  "day": 1,
  "dead": 1,
  "decide": 2,
  "decrease": 2,
  "deep": 1,
  "deer": 2,
  "depend": 2,
  "desk": 1,
  "destroy": 2,
  "develop": 3,
  "die": 1,
  "different": 2,
  "difficult": 3,
  "dinner": 2,
  "direction": 3,
  "dirty": 2,
  "discover": 3,
  "dish": 1,
  "do": 1,
  "dog": 1,
  "door": 1,
  "double": 2,
  "down": 1,
  "draw": 1,
  "dream": 1,
  "dress": 1,
  "drink": 1,
  "drive": 1,
  "drop": 1,
  "dry": 1,
  "duck": 1,
  "dust": 1,
  "duty": 2,
  "each": 1,
  "ear": 2,
  "early": 2,
  "earn": 1,
  "earth": 1,
  "east": 1,
  "easy": 2,
  "eat": 1,
  "education": 4,
  "effect": 2,
  "egg": 1,
  "eight": 1,
  "either": 2,
  "electric": 3,
  "elephant": 3,
  "else": 1,
  "empty": 2,
  "end": 1,
  "enemy": 3,
  "enjoy": 2,
  "enough": 2,
  "enter": 2,
  "entrance": 2,
  "equal": 2,
  "escape": 2,
  "even": 2,
  "evening": 2,
  "event": 2,
  "ever": 2,
  "every": 2,
  "everybody": 4,
  "everyone": 3,
  "exact": 2,
  "examination": 5,
  "example": 3,
  "except": 2,
  "excited": 3,
  "exercise": 3,
  "expect": 2,
  "expensive": 3,
  "explain": 2,
  "extremely": 3,
  "eye": 1,
  "face": 1,
  "fact": 1,
  "fail": 2,
  "fall": 1,
  "false": 1,
  "family": 2,
  "famous": 2,
  "far": 1,
  "farm": 1,
  "fast": 1,
  "fat": 1,
  "father": 2,
  "fault": 1,
  "fear": 2,
  "feed": 1,
  "feel": 2,
  "female": 3,
  "fever": 2,
  "few": 1,
  "fight": 1,
  "fill": 1,
  "film": 1,
  "find": 1,
  "fine": 1,
  "finger": 2,
  "finish": 2,
  "fire": 2,
  "first": 1,
  "fit": 1,
  "five": 1,
  "fix": 1,
  "flag": 1,
  "flat": 1,
  "float": 1,
  "floor": 1,
  "flour": 2,
  "flower": 2,
  "fly": 1,
  "fold": 1,
  "food": 1,
  "fool": 1,
  "foot": 1,
  "football": 2,
  "for": 1,
  "force": 1,
  "foreign": 2,
  "forest": 2,
  "forget": 2,
  "forgive": 2,
  "fork": 1,
  "form": 1,
  "four": 1,
  "fox": 1,
  "free": 1,
  "freedom": 2,
  "freeze": 1,
  "fresh": 1,
  "friend": 1,
  "friendly": 2,
  "from": 1,
  "front": 1,
  "fruit": 1,
  "full": 1,
  "fun": 1,
  "funny": 2,
  "furniture": 3,
  "further": 2,
  "future": 2,
  "game": 1,
  "garden": 2,
  "gate": 1,
  "general": 2,
  "gentleman": 3,
  "get": 1,
  "gift": 1,
  "give": 1,
  "glad": 1,
  "glass": 1,
  "go": 1,
  "goat": 1,
  "god": 1,
  "gold": 1,
  "good": 1,
  "goodbye": 2,
  "grandfather": 3,
  "grandmother": 3,
  "grass": 1,
  "grave": 1,
  "great": 1,
  "green": 1,
  "grey": 1,
  "ground": 1,
  "group": 1,
  "grow": 1,
  "gun": 1,
  "hair": 1,
  "half": 1,
  "hall": 1,
  "hammer": 2,
  "hand": 1,
  "happen": 2,
  "happy": 2,
  "hard": 1,
  "hat": 1,
  "hate": 1,
  "have": 1,
  "he": 1,
  "head": 1,
  "healthy": 2,
  "hear": 2,
  "heart": 1,
  "heaven": 2,
  "heavy": 2,
  "height": 1,
  "hello": 2,
  "help": 1,
  "hen": 1,
  "her": 1,
  "here": 2,
  "hers": 1,
  "hide": 1,
  "high": 1,
  "hill": 1,
  "him": 1,
  "his": 1,
  "hit": 1,
  "hobby": 2,
  "hold": 1,
  "hole": 1,
  "holiday": 3,
  "home": 1,
  "hope": 1,
  "horse": 1,
  "hospital": 3,
  "hot": 1,
  "hotel": 2,
  "hour": 2,
  "house": 1,
  "how": 1,
  "hundred": 2,
  "hungry": 2,
  "hurry": 2,
  "hurt": 1,
  "husband": 2,
  "I": 1,
  "ice": 1,
  "idea": 3,
  "if": 1,
  "important": 3,
  "in": 1,
  "increase": 2,
  "inside": 2,
  "into": 2,
  "introduce": 3,
  "invent": 2,
  "invite": 2,
  "iron": 2,
  "is": 1,
  "island": 2,
  "it": 1,
  "its": 1,
  "jelly": 2,
  "job": 1,
  "join": 1,
  "juice": 1,
  "jump": 1,
  "just": 1,
  "keep": 1,
  "key": 1,
  "kill": 1,
  "kind": 1,
  "king": 1,
  "kitchen": 2,
  "knee": 1,
  "knife": 1,
  "knock": 1,
  "know": 1,
  "ladder": 2,
  "lady": 2,
  "lamp": 1,
  "land": 1,
  "large": 1,
  "last": 1,
  "late": 1,
  "lately": 2,
  "laugh": 1,
  "lazy": 2,
  "lead": 1,
  "leaf": 1,
  "learn": 1,
  "leave": 1,
  "left": 1,
  "leg": 1,
  "lend": 1,
  "length": 1,
  "less": 1,
  "lesson": 2,
  "let": 1,
  "letter": 2,
  "library": 2,
  "lie": 1,
  "life": 1,
  "light": 1,
  "like": 1,
  "lion": 2,
  "lip": 1,
  "list": 1,
  "listen": 2,
  "little": 2,
  "live": 1,
  "lock": 1,
  "lonely": 2,
  "long": 1,
  "look": 1,
  "lose": 1,
  "lot": 1,
  "love": 1,
  "low": 1,
  "lower": 2,
  "luck": 1,
  "machine": 2,
  "main": 1,
  "make": 1,
  "male": 2,
  "man": 1,
  "many": 2,
  "map": 1,
  "mark": 1,
  "market": 2,
  "marry": 2,
  "matter": 2,
  "may": 1,
  "me": 1,
  "meal": 2,
  "mean": 1,
  "measure": 2,
  "meat": 1,
  "medicine": 3,
  "meet": 1,
  "member": 2,
  "mention": 2,
  "method": 2,
  "middle": 2,
  "milk": 1,
  "million": 2,
  "mind": 1,
  "minute": 2,
  "miss": 1,
  "mistake": 2,
  "mix": 1,
  "model": 2,
  "modern": 2,
  "moment": 2,
  "money": 2,
  "monkey": 2,
  "month": 1,
  "moon": 1,
  "more": 1,
  "morning": 2,
  "most": 1,
  "mother": 2,
  "mountain": 2,
  "mouth": 1,
  "move": 1,
  "much": 1,
  "music": 2,
  "must": 1,
  "my": 1,
  "name": 1,
  "narrow": 2,
  "nation": 2,
  "nature": 2,
  "near": 2,
  "nearly": 2,
  "neck": 1,
  "need": 1,
  "needle": 2,
  "neighbour": 2,
  "neither": 2,
  "net": 1,
  "never": 2,
  "new": 1,
  "news": 1,
  "newspaper": 3,
  "next": 1,
  "nice": 1,
  "night": 1,
  "nine": 1,
  "no": 1,
  "noble": 2,
  "noise": 1,
  "none": 1,
  "nor": 1,
  "north": 1,
  "nose": 1,
  "not": 1,
  "nothing": 2,
  "notice": 2,
  "now": 1,
  "number": 2,
  "obey": 2,
  "object": 2,
  "ocean": 2,
  "of": 1,
  "off": 1,
  "offer": 2,
  "office": 2,
  "often": 2,
  "oil": 2,
  "old": 1,
  "on": 1,
  "one": 1,
  "only": 2,
  "open": 2,
  "opposite": 3,
  "or": 1,
  "orange": 2,
  "order": 2,
  "other": 2,
  "our": 2,
  "out": 1,
  "outside": 2,
  "over": 2,
  "own": 1,
  "page": 1,
  "pain": 1,
  "paint": 1,
  "pair": 1,
  "pan": 1,
  "paper": 2,
  "parent": 2,
  "park": 1,
  "part": 1,
  "partner": 2,
  "party": 2,
  "pass": 1,
  "past": 1,
  "path": 1,
  "pay": 1,
  "peace": 1,
  "pen": 1,
  "pencil": 2,
  "people": 2,
  "pepper": 2,
  "per": 1,
  "perfect": 2,
  "period": 3,
  "person": 2,
  "petrol": 2,
  "photograph": 3,
  "piano": 3,
  "pick": 1,
  "picture": 2,
  "piece": 1,
  "pig": 1,
  "pin": 1,
  "pink": 1,
  "place": 1,
  "plane": 1,
  "plant": 1,
  "plastic": 2,
  "plate": 1,
  "play": 1,
  "please": 1,
  "pleased": 1,
  "plenty": 2,
  "pocket": 2,
  "point": 1,
  "poison": 2,
  "police": 1,
  "polite": 2,
  "pool": 1,
  "poor": 1,
  "popular": 3,
  "position": 3,
  "possible": 3,
  "potato": 3,
  "pour": 1,
  "power": 2,
  "present": 2,
  "press": 1,
  "pretty": 2,
  "prevent": 2,
  "price": 1,
  "prince": 1,
  "prison": 2,
  "private": 2,
  "prize": 1,
  "probably": 3,
  "problem": 2,
  "produce": 2,
  "promise": 2,
  "proper": 2,
  "protect": 2,
  "provide": 2,
  "public": 2,
  "pull": 1,
  "punish": 2,
  "pupil": 2,
  "push": 1,
  "put": 1,
  "queen": 1,
  "question": 2,
  "quick": 1,
  "quiet": 2,
  "quite": 1,
  "radio": 3,
  "rain": 1,
  "rainy": 2,
  "raise": 1,
  "reach": 1,
  "read": 1,
  "ready": 2,
  "real": 2,
  "really": 2,
  "receive": 2,
  "record": 2,
  "red": 1,
  "remember": 3,
  "remind": 2,
  "remove": 2,
  "rent": 1,
  "repair": 2,
  "repeat": 2,
  "reply": 2,
  "report": 2,
  "rest": 1,
  "restaurant": 2,
  "result": 2,
  "return": 2,
  "rice": 1,
  "rich": 1,
  "ride": 1,
  "right": 1,
  "ring": 1,
  "rise": 1,
  "road": 1,
  "rob": 1,
  "rock": 1,
  "room": 1,
  "round": 1,
  "rubber": 2,
  "rude": 1,
  "rule": 1,
  "ruler": 2,
  "run": 1,
  "rush": 1,
  "sad": 1,
  "safe": 1,
  "sail": 2,
  "salt": 1,
  "same": 1,
  "sand": 1,
  "save": 1,
  "say": 1,
  "school": 1,
  "science": 2,
  "scissors": 2,
  "search": 1,
  "seat": 1,
  "second": 2,
  "see": 1,
  "seem": 1,
  "sell": 1,
  "send": 1,
  "sentence": 2,
  "serve": 1,
  "seven": 2,
  "several": 2,
  "sex": 1,
  "shade": 1,
  "shadow": 2,
  "shake": 1,
  "shape": 1,
  "share": 1,
  "sharp": 1,
  "she": 1,
  "sheep": 1,
  "sheet": 1,
  "shelf": 1,
  "shine": 1,
  "ship": 1,
  "shirt": 1,
  "shoe": 1,
  "shoot": 1,
  "shop": 1,
  "short": 1,
  "should": 1,
  "shoulder": 2,
  "shout": 1,
  "show": 1,
  "sick": 1,
  "side": 1,
  "signal": 2,
  "silence": 2,
  "silly": 2,
  "silver": 2,
  "similar": 3,
  "simple": 2,
  "since": 1,
  "sing": 1,
  "single": 2,
  "sink": 1,
  "sister": 2,
  "sit": 1,
  "six": 1,
  "size": 1,
  "skill": 1,
  "skin": 1,
  "skirt": 1,
  "sky": 1,
  "sleep": 1,
  "slip": 1,
  "slow": 1,
  "small": 1,
  "smell": 1,
  "smile": 2,
  "smoke": 1,
  "snow": 1,
  "so": 1,
  "soap": 1,
  "sock": 1,
  "soft": 1,
  "some": 1,
  "someone": 2,
  "something": 2,
  "sometimes": 2,
  "son": 1,
  "soon": 1,
  "sorry": 2,
  "sound": 1,
  "soup": 1,
  "south": 1,
  "space": 1,
  "speak": 1,
  "special": 2,
  "speed": 1,
  "spell": 1,
  "spend": 1,
  "spoon": 1,
  "sport": 1,
  "spread": 1,
  "spring": 1,
  "square": 1,
  "stamp": 1,
  "stand": 1,
  "star": 1,
  "start": 1,
  "station": 2,
  "stay": 1,
  "steal": 2,
  "steam": 1,
  "step": 1,
  "still": 1,
  "stomach": 1,
  "stone": 1,
  "stop": 1,
  "store": 1,
  "storm": 1,
  "story": 2,
  "strange": 1,
  "street": 1,
  "strong": 1,
  "structure": 2,
  "student": 2,
  "study": 2,
  "stupid": 2,
  "subject": 2,
  "substance": 2,
  "successful": 3,
  "such": 1,
  "sudden": 2,
  "sugar": 2,
  "suitable": 3,
  "summer": 2,
  "sun": 1,
  "sunny": 2,
  "support": 2,
  "sure": 1,
  "surprise": 2,
  "sweet": 1,
  "swim": 1,
  "sword": 1,
  "table": 2,
  "take": 1,
  "talk": 1,
  "tall": 1,
  "taste": 1,
  "taxi": 2,
  "tea": 1,
  "teach": 1,
  "team": 1,
  "tear": [1, 2],
  "telephone": 3,
  "television": 4,
  "tell": 1,
  "ten": 1,
  "tennis": 2,
  "terrible": 3,
  "test": 1,
  "than": 1,
  "that": 1,
  "the": 1,
  "their": 1,
  "then": 1,
  "there": 1,
  "therefore": 2,
  "these": 1,
  "thick": 1,
  "thin": 1,
  "thing": 1,
  "think": 1,
  "third": 1,
  "this": 1,
  "though": 1,
  "threat": 1,
  "three": 1,
  "tidy": 2,
  "tie": 1,
  "title": 2,
  "to": 1,
  "today": 2,
  "toe": 1,
  "together": 3,
  "tomorrow": 3,
  "tonight": 2,
  "too": 1,
  "tool": 1,
  "tooth": 1,
  "top": 1,
  "total": 2,
  "touch": 1,
  "town": 1,
  "train": 1,
  "tram": 1,
  "travel": 2,
  "tree": 1,
  "trouble": 2,
  "true": 1,
  "trust": 1,
  "try": 1,
  "turn": 1,
  "twice": 1,
  "type": 1,
  "uncle": 2,
  "under": 2,
  "understand": 3,
  "unit": 2,
  "until": 2,
  "up": 1,
  "use": 1,
  "useful": 2,
  "usual": 2,
  "usually": 3,
  "vegetable": 3,
  "very": 2,
  "village": 2,
  "visit": 2,
  "voice": 1,
  "wait": 1,
  "wake": 1,
  "walk": 1,
  "want": 1,
  "warm": 1,
  "wash": 1,
  "waste": 1,
  "watch": 1,
  "water": 2,
  "way": 1,
  "we": 1,
  "weak": 1,
  "wear": 1,
  "weather": 2,
  "wedding": 2,
  "week": 1,
  "weight": 1,
  "welcome": 2,
  "well": 1,
  "west": 1,
  "wet": 1,
  "what": 1,
  "wheel": 2,
  "when": 1,
  "where": 1,
  "which": 1,
  "while": 2,
  "white": 1,
  "who": 1,
  "why": 1,
  "wide": 1,
  "wife": 1,
  "wild": 2,
  "will": 1,
  "win": 1,
  "wind": 1,
  "window": 2,
  "wine": 1,
  "winter": 2,
  "wire": 2,
  "wise": 1,
  "wish": 1,
  "with": 1,
  "without": 2,
  "woman": 2,
  "wonder": 2,
  "word": 1,
  "work": 1,
  "world": 1,
  "worry": 2,
  "worst": 1,
  "write": 1,
  "wrong": 1,
  "year": 2,
  "yes": 1,
  "yesterday": 3,
  "yet": 1,
  "you": 1,
  "young": 1,
  "your": 1,
  "zero": 2,
  "zoo": 1
};

function checkcode(e) {
  var t = document.getElementById('words').value;
  var re = new RegExp(/^(\w+),(\d+)/gm);
  var lines = t.match(re);
  re = new RegExp(/^(\w+),(\d+)/);
  if (!lines) {
    lines = [];
  }
  var keys = JSON.parse(JSON.stringify(syl));
  var tally = [];
  var wrong = [];
  for (i = 0; i < lines.length; ++i) {
    var num = lines[i].match(re);
    if (num[1] in syl) {
      var res = num[1] !== "tear"? Math.abs(syl[num[1]] - num[2]): Math.min(Math.abs(syl[num[1]][0] - num[2]), Math.abs(syl[num[1]][1] - num[2]));
      if (!(res in tally)) {
        tally[res] = 0;
      }
      ++tally[res];
      if (res) {
        wrong.push(num[1] + " *" + num[2] + ", (" + syl[num[1]] + ")");
      }
      delete(keys[num[1]]);
    }
  }
  for (i in keys) {
    if (!(keys[i] in tally)) {
      tally[keys[i]] = 0;
    }
    ++tally[keys[i]];
  }
  var score = 0;
  for (i = 0; i < tally.length; ++i) {
    if (i in tally) {
      score += i * (i + 1) * tally[i] * (tally[i] + 1) / 4;
    }
  }
  var missing = 0;
  var missinglist = []
  for (i in keys) {
    missinglist.push(i + "," + keys[i]);
    ++missing;
  }
  codescore = document.getElementById("code").value.length;
  codescore = document.getElementById("code").value;
  if (codescore.match(/[^\u0000-\u00FF]/)) {
    cs1 = codescore.match(/[\u0000-\u007F]/g);
    cs2 = codescore.match(/[\u0080-\u07FF]/g);
    cs3 = codescore.match(/[\u0800-\uFFFF]/g);
    codescore = (cs1? cs1.length: 0) + (cs2? cs2.length * 2: 0) + (cs3? cs3.length * 3: 0);
  }
  else {
    codescore = codescore.length;
  }
  codescore *= 60;
  document.getElementById("result").value = "Code score: " + codescore + "\nWord score: " + score + "\nTotal score: " + (codescore + score) + "\nValid lines: " + lines.length + "\nMissing words: " + missing + "\n\nMissing words:\n" + missinglist.join("\n") + "\n\nWrong number:\n" + wrong.join("\n");
}
```

```
textarea {
        width: 320px;
        height: 480px;
      }

      textarea#code {
        width: 650px;
        height: 80px;
      }

      span {
        display: inline-block;
      }
```

```
<span>Code:<br/>
    <textarea id="code">
</textarea></span><br/>
    <span>Output:<br/>
    <textarea id="words">
</textarea></span>
    <span>Score:<br/><textarea id="result" disabled="disabled">
</textarea></span><br/>
    <input type="submit" onclick="checkcode(this)"/>
```

The variant of English used for the syllables is Australian English, spoken slower than usual. There is one word in the list that has two pronunciations with different numbers of syllables: `tear` to rip, 1 syllable; and water from the eye, 2 syllables (te-ar). Either `tear,1` or `tear,2` is correct for this word. I have gone through the whole list twice, but there might be some errors. Please don't complain that a particular word has a different number of syllables in British, American, etc. English. I will only make changes to the expected number of syllables if I agree that the number of syllables is wrong in Australian English.

Standard Code Golf rules with custom scoring.

# Answer
> 1 votes
# Mathematica, score 4560 (code) + 1128 (words) = 5688 (total)

```
""<>({#,",",ToString@Length[#~WordData~"Hyphenation"],"
"}&/@StringSplit@#)&

```

Anonymous function. Uses Mathematica's built-in `WordData`. For reference, here are the incorrect words (some of which I disagree with):

```
appear *2, (3)
beer *1, (2)
boil *1, (2)
chocolate *3, (2)
clear *1, (2)
colour *1, (2)
comfortable *4, (3)
deer *1, (2)
different *3, (2)
ear *1, (2)
fail *1, (2)
family *3, (2)
fear *1, (2)
feel *1, (2)
female *2, (3)
fire *1, (2)
flour *1, (2)
general *3, (2)
hear *1, (2)
here *1, (2)
hour *1, (2)
library *3, (2)
male *1, (2)
meal *1, (2)
near *1, (2)
oil *1, (2)
our *1, (2)
over *1, (2)
petrol *1, (2)
piano *2, (3)
police *2, (1)
really *3, (2)
restaurant *3, (2)
sail *1, (2)
several *3, (2)
smile *1, (2)
steal *1, (2)
stomach *2, (1)
tidy *1, (2)
usual *3, (2)
usually *4, (3)
vegetable *4, (3)
wheel *1, (2)
while *1, (2)
wild *1, (2)
wire *1, (2)
year *1, (2)

```

# Answer
> 1 votes
# Ruby, 5160 code + 4008 words = 9168

```
->l{l.lines{|w|print w.chop,?,,w.sub("e\n","").tr_s('aeiouy','******').count('*'),$/}}

```

Anonymous function. Expects as an argument all the words in a single string, newline separated, (as direct from pastebin.) Requires a trailing newline in order to print `zoo` correctly (can be fixed for 1 byte if required.)

**ungolfed**

```
f=->l{                       #Lambda assigned to varible f. Call as f[list]
  l.lines{|w|                #for each line, complete with newline
    print w.chop,?,,         #print the word with the newline removed, and a comma, and the following:
    w.sub("e\n","").         #Take the word. If there is an (e and newline) at the end remove them
    tr_s('aeiouy','******'). #convert all vowel clusters to a single *
    count('*'),              #and count the stars
    $/                       #finally print a newline ($/ is a special variable holding the line separator, newline by default.)
  }
}

```

**wrong words**

About twice as many as Legionmamma's mathematica answer.

I've marked 3 common and easy to fix errors. Whether difference in code length is worth it is another matter. I might get back to this later.

```
anyone *2, (3)
appear *2, (3)
apple *1, (2)             #A consonant+le ending (19 incidences)
area *2, (3)
be *0, (1)                #B words must have at least one syllable (7 incidences)
beer *1, (2)
besides *3, (2)           #C es ending (3 incidences)
boil *1, (2)
bottle *1, (2)            #A
business *3, (2)
candle *1, (2)            #A
careful *3, (2)
careless *3, (2)
chocolate *3, (2)
circle *1, (2)            #A
clear *1, (2)
clothes *2, (1)           #C
deer *1, (2)
different *3, (2)
double *1, (2)            #A
ear *1, (2)
evening *3, (2)
every *3, (2)
everybody *5, (4)
example *2, (3)           #A
extremely *4, (3)
fail *1, (2)
family *3, (2)
fear *1, (2)
feel *1, (2)
female *2, (3)
fire *1, (2)
flour *1, (2)
general *3, (2)
he *0, (1)                #B
hear *1, (2)
here *1, (2)
hour *1, (2)
I *0, (1)                 #B
idea *2, (3)
lately *3, (2)
library *3, (2)
lion *1, (2)
little *1, (2)            #A
lonely *3, (2)
male *1, (2)
me *0, (1)                #B
meal *1, (2)
middle *1, (2)            #A
near *1, (2)
needle *1, (2)            #A
noble *1, (2)             #A
oil *1, (2)
our *1, (2)
people *1, (2)            #A
period *2, (3)
piano *2, (3)
pleased *2, (1)
police *2, (1)
possible *2, (3)
quiet *1, (2)
radio *2, (3)
real *1, (2)
restaurant *3, (2)
sail *1, (2)
science *1, (2)
several *3, (2)
she *0, (1)               #B
simple *1, (2)            #A
single *1, (2)            #A
smile *1, (2)
something *3, (2)
sometimes *4, (2)         #C
steal *1, (2)
stomach *2, (1)
suitable *2, (3)          #A
table *1, (2)             #A
terrible *2, (3)          #A
the *0, (1)               #B
therefore *3, (2)
title *1, (2)             #A
trouble *1, (2)           #A
uncle *1, (2)             #A
useful *3, (2)
we *0, (1)                #B
wheel *1, (2)
while *1, (2)
wild *1, (2)
wire *1, (2)
year *1, (2)

```

---
Tags: code-golf, kolmogorov-complexity, natural-language
---


title: Brass Fingerings

text:
# Question
Title: Brass Fingerings
For this challenge, you need to print out the fingerings for various brass instruments.

The notes an instrument can play (as well as their fingerings) are listed below:

```
    Cornet                       Baritone
    Trumpet  Bugle  French Horn  Euphonium  Tuba
A#0                                         0
B0
C1                                          1234
C#1                                         134
D1                                          234
D#1                                         14
E1                                          24
F1                                          4
F#1                                         23
G1                                          12
G#1                                         1
A1                                          2
A#1                              0          0
B1                  123          1234       24
C2                  13           134        4
C#2                 23           234        23
D2                  12           124        12
D#2                 1            14         1
E2                  2            24         2
F2                  0            4          0
F#2                 123          23         23
G2                  13           12         12
G#2                 23           1          1
A2                  12           2          2
A#2                 1            0          0
B2                  2            24         12
C3                  0            4          1
C#3                 23           23         2
D3                  12           12         0
D#3                 1            1          1
E3  123             2            2          2
F3  13              0            0          0
F#3 23              12           23         23
G3  12              1            12         12
G#3 1               2            1          1
A3  2               0            2          2
A#3 0               1            0          0
B3  123             2            12         12
C4  13              0            1          1
C#4 23              23           2          2
D4  12              12           0          0
D#4 1               1            1          1
E4  2               2            2          2
F4  0               0            0          0
F#4 23              2            23         23
G4  12       0      0            12         12
G#4 1               2            1          1
A4  2               0            2          2
A#4 0               1            0          0
B4  12              2            12
C5  1        0      0            1
C#5 2               23           2
D5  0               12           0
D#5 1               1            1
E5  2        0      2            2
F5  0               0            0
F#5 23
G5  12       0
G#5 1
A5  2
A#5 0

```

# Input

* A single string with a name of an instrument. You can assume the name will always be one of the 7 listed above.
* A note, which can be a single string or a string and integer. You can assume the note will match one of the notes listed above.

# Output

* The fingering for the note on that instrument. This can either be a list of integers (one for each digit), or a single integer.
* If the instrument cannot play a given note (listed as blank above), return `"Impossible"`

# Test Cases

```
Cornet D#3        Impossible
Cornet E3         123
Trumpet G4        12
Trumpet B4        12
Trumpet F#5       23
Bugle F#5         Impossible
Bugle G5          0
Bugle G1          Impossible
French Horn B1    123
French Horn C3    0
French Horn E5    2
French Horn A#5   Impossible
Baritone A#5      Impossible
Baritone A#2      0
Baritone B2       24
Baritone B1       1234
Euphonium F2      4
Tuba A#0          0
Tuba B0           Impossible
Tuba C1           1234
Tuba B1           24
Tuba G#4          1
Tuba B4           Impossible

```

# Notes

* Trumpet and Cornet have the same fingerings, as well as Baritone and Euphonium
* These ranges aren't comprehensive. I've tried to stick to the "standard" notes, but instruments can often go below (pedal notes) or above.
* The notes listed are in concert pitch
* You'll notice that there are a lot of patterns between the fingerings. Finding those patterns is critical to golfing this well.

This is a , so the shortest answer in your favorite language wins!

# Answer
# Ruby, 292

```
->i,n{t='nberlu'.index(i[-2])%5
u,v=t<2?[4,24]:[13,123]
a=[]
'!&)+-259>EQR'.tr(?+,t==3??+:?)).bytes{|i|a[i,1]=[0,2,1,12,23,u,v,14,124,234,134,1234]}
p=n[0].ord*13/8%12+n[-1].to_i*12+n.size
p<17&&p-=1
f=a[x='i]udw'[t].ord-p]
('&!-!2'[t]..'QRKK>'[t])===x.chr&&p!=12&&(t<4||1>f)?f:"impossible"}

```

**Explanation**

The table below shows more clearly the similarities and differences between the instruments. Basically, a fingering of 0 corresponds to one of the harmonics of the main tube. Not all harmonics are available on all instruments. For example the French horn is the only one to use the 9th harmonic. Differences are apparent by spaces in the table, or highlighted with `*`

The bugle is simplest and has no valves. The other instruments have at least 3 valves. Valves are used to add bits of tube to the basic instrument to lower the pitch. Valve 2=-1 semitone, Valve 1=-2 semitones, Valve 3=-3 semitones, and valve 4 (if present) is -5 semitones. Valve 4 extends the range of the lower instruments, and is also used as an alternative fingering `4` or `24` for notes which are fingered as `13`or `123` on instruments without a 4th valve.

All the notes from a particular harmonic downwards are fingered in the same way, up until the next harmonic down is reached. The harmonics are quite closely spaced in the upper range, but get sparser in the lower range. At the start of the code a table is built from the highest harmonic downwards by repeatedly inserting a complete set of 12 fingerings into the array. Some fingerings are unused because another harmonic is encountered before the lower fingerings are required. This data is not overwritten, it is pushed to the end of the array, so the end of the array contains a lot of garbage, but this does not matter.

Then all we have to do is transpose the input to the right place on the table and return the fingering. Also, we have to check if the note is in range. Rather than do this with the note itself, I do it with the position in the table of fingerings. This uses a more limited range of values.

```
   Corn         Bari
   Trum Bug HornEuphTuba
No                      ASC char    harmonic

49                  0   82  R   fundamental (repeat for tuba)
48              0   0   81  Q   fundamental (not available on tuba)
47              12341234
46              134 134
45              234 234
44              124
43              14  14
42  123*    123*24  24
41  13*     13* 4   4
40  23      23  23  23
39  12      12  12  12
38  1       1   1   1
37  2       2   2   2
36  0       0   0   0   69  E   2nd harmonic
35  123*    123*24  24
34  13*     13* 4   4
33  23      23  23  23
32  12      12  12  12
31  1       1   1   1
30  2       2   2   2
29  0   0   0   0   0   62  >   3rd harmonic
28  23      23  23  23
27  12      12  12  12
26  1       1   1   1
25  2       2   2   2
24  0   0   0   0   0   57  9   4th harmonic
23  12      12  12  12
22  1       1   1   1
21  2       2   2   2
20  0   0   0   0   0   53  5   5th harmonic
19  1       1   1   1
18  2       2   2   2
17  0   0   0   0   0   50  2   6th harmonic
16  23      23  23  23
15  12      12  12  12
14  1       1   1   1
13  2       2   2   2
12  0       0   0   0   45  -   8th harmonic
11          2*  12  12
10          0*  1   1   43  +   9th harmonic
9           2   2   2
8           0   0   0   41  )   10th harmonic
7           1   1   1
6           2   2   2
5           0   0   0   38  &   12th harrmonic
4           23      23
3           12      12
2           1       1
1           2       2
0           0       0   33  !   16th harmonic

```

**commented in test program**

```
#penultimate letter of instrument
                    range     16th harmonic
#n 0 baritone       A#1-F5    A#5
#b 1 tuba           A#0-A#4   A#4
#e 2 trumpet,cornet E3-A#5    A#6
#r 3 french horn    B1-F5     F5
#l 4 bugle          G4-G5     C7
#u 0 euphonium
g=->i,n{
  t='nberlu'.index(i[-2])%5                  #translate instrument into code above according to penultimate letter of name
  u,v=t<2?[4,24]:[13,123]                    #select fingerings for 4 valve or 3 valve instruments
  a=[]                                       #empty fingerings table
  '!&)+-259>EQR'.                            #list of harmonics as ascii codes + =9th harmonic, only on french horn
    tr(?+,t==3??+:?)).                       #if not french horn, delete the + and replace with duplicate of symbol before it )
      bytes{|i|a[i,1]=                       #for each value in the string, insert a complete table of 12 fingerings into a,
       [0,2,1,12,23,u,v,14,124,234,134,1234]}#pushing garbage fingerings to the end
   p=n[0].ord*13/8%12+                       #pitch of note depends on note name
     n[-1].to_i*12+n.size                    #+12*octave number. Length of string is 1 longer for sharp, so add this also.
   p<17&&p-=1                                #for tuba, consider pitch lowered by 1 if below D#1 to skip over the 124 fingering
   f=a[x='i]udw'[t].ord-p]                   #subtract p from 'i]udw'[t].ord to find x, the position of the fingering in the table. Assign the actual fingering to f
   ('&!-!2'[t]..'QRKK>'[t])===x.chr&&        #if x is in the range for the instrument
     p!=12&&                                 #and the note is not B0 (missing for tuba, completely out of range for other instruments)
    (t<4||1>f)?                              #and the instrument is not a bugle (or if it is, the fingering is 0)
      f:"impossible"                         #return the fingering. Otherwise return impossible.
}

[['Cornet','D#3'],       #Impossible
['Cornet','E3'],         #123
['Trumpet','G4'],        #12
['Trumpet','B4'],        #12
['Trumpet','F#5'],       #23
['Trumpet','A#5'],        #0
['Trumpet','B5'],         #Impossible

['Bugle','F#5'],         #Impossible
['Bugle','G5'],          #0
['Bugle','G1'],          #Impossible
['Bugle','C4'],           #Impossible
['Bugle','G4'],           #0
['Bugle','C6'],           #Impossible

['French Horn','A#1'],    #Impossible
['French Horn','B1'],    #123
['French Horn','C3'],    #0
['French Horn','E5'],    #2
['French Horn','F5'],     #0
['French Horn','F#5'],    #Impossible
['French Horn','A#5'],   #Impossible

['Baritone','A#5'],      #Impossible
['Baritone','A#2'],      #0
['Baritone','B2'],       #24
['Baritone','A1'],        #Impossible
['Baritone','A#1'],       #0
['Baritone','B1'],       #1234
['Euphonium','F2'],      #4
['Euphonium','F5'],       #0
['Euphonium','F#5'],      #Impossible

['Tuba','A#0'],          #0
['Tuba','B0'],           #Impossible
['Tuba','C1'],           #1234
['Tuba','C#1'],           #134
['Tuba','D1'],            #234
['Tuba','D#1'],           #14
['Tuba','B1'],           #24
['Tuba','G#4'],          #1
['Tuba','A#4'],           #0
['Tuba','B4']].each{|c|  #Impossible
  puts c
  puts g[c[0],c[1]]
  puts
}

```
> 2 votes

---
Tags: code-golf, music
---


title: Mathematical substitution

text:
# Question
Title: Mathematical substitution
Sometimes it is useful to run a math problem with multiple inputs. The goal of this challenge is to make a program that eases this task.

## Number-generating expressions

You must support 3 types of expression:

* Single number generator: Very simple, just a literal number
* Multi-number generator: A tad more complicated. Thees are surrounded by square brackets (`[]`). Numbers are comma (`,`) separated in the expression. Example `[-1,2,3.26]`.
* Range generator: This one is surrounded by curly braces (`{}`). It will have 3 numbers separated by a comma. The format of this expression is `{start,stop,step}`. `start` and `stop` are inclusive.

## Rules for evaluation

* You must support the order of operations. (https://en.wikipedia.org/wiki/Order\_of\_operations#Definition)
* You don't need to support parenthesis.
* Any number of spaces may occur in the expression.
* You must support floating point numbers (whatever precision your language defaults to is fine).
* Division by `0` results in `NaN` (not a number).

Your program must support multiplication (`*`), division (`/`), addition (`+`) and subtraction (`-`).

## Output

Each line of output is one of the combinations of the generators. The format is the expression (with the real numbers substituted into it) followed by a equals sign (`=`) and the result of evaluation. All combinations of the generators must be represented in the output.

## Examples

(`>>>` denotes input)

```
>>>3 * [3,2]
3 * 3 = 9
3 * 2 = 6

>>>{1,2,3}
1 = 1 <-- this is because 1 + 3 > the end

>>>{0,2,1} + {0,1,1}
0 + 0 = 0
1 + 0 = 1
2 + 0 = 2
0 + 1 = 1
1 + 1 = 2
2 + 1 = 3

>>>6/[2,3]
6/2 = 3
6/3 = 2

>>>{1.5,2.5,0.5}
1.5 = 1.5
2 = 2
2.5 = 2.5

>>>3-{6,5,-1}
3-6 = -3
3-5 = -2

>>>5/{-1,1,1}
5/-1 = -5
5/0 = NaN
5/1 = 5

>>>4.4 / [1,2.2] + {0,2,1}
4.4 / 1 + 0 = 4.4
4.4 / 1 + 1 = 5.4
4.4 / 1 + 2 = 6.4
4.4 / 2.2 + 0 = 2
4.4 / 2.2 + 1 = 3
4.4 / 2.2 + 2 = 4

>>> [1,2] / 0 + 5
1 / 0 + 5 = NaN
2 / 0 + 5 = NaN

```

The program needs to be short so I can memorizes it and use it anywhere.

Thanks to @PeterTaylor and @geokavel for helping me with this post in the sandbox

# Answer
> 4 votes
# JavaScript (ES6), ~~213~~ 211 bytes

```
f=x=>(a=0,x=x.replace(/\[.+?]|{.+?}/,r=>([i,l,n]=a=r.slice(1,-1).split`,`,r[0]>"]"&&eval(`for(a=[];n>0?i<=+l:i>=+l;i-=-n)a.push(i)`),"x")),a?a.map(n=>f(x.replace("x",n))).join``:x+` = ${r=eval(x),r<1/0?r:NaN}
`)

```

## Explanation

A recursive function that executes the expression if it does not contain any multi-number or range generators, or if it does contain one of these generators, calls itself with the generator replaced with each number produced by it.

Dividing by `0` in JavaScript produces `Infinity`, so `Infinity` can simply be replaced with `NaN`.

Using this method the multi-generators are parsed from back-to-front instead of front-to-back like in the test cases. This just means the order of the output expressions is different sometimes.

```
f=x=>(
  a=0,                                           // initialise a to false
  x=x.replace(/\[.+?]|{.+?}/,r=>(                // find the first multi-generator
    [i,l,n]=                                     // i = start, l = stop, n = step
      a=r.slice(1,-1).split`,`,                  // a = each number of generator
    r[0]>"]"&&                                   // if a range generator was found
      eval(`                                     // use eval to enable for loop here
        for(a=[];n>0?i<=+l:i>=+l;i-=-n)a.push(i) // add each number of the range to a
      `),
    "x"                                          // replace the generator with "x"
  )),
  a?                                             // if a multi-generator was found
    a.map(n=>                                    // for each number n in a
      f(x.replace("x",n))                        // call itself with n inserted
    )
    .join``                                      // combine the output of each result
  :x+` = ${r=eval(x),                            // evaluate the expression
    r<1/0?r:NaN}
`                                                // replace Infinity with NaN
)

```

## Test

Test does not use destructuring assignments for browser compatibility.

```
f=x=>(a=0,x=x.replace(/\[.+?]|{.+?}/,r=>(a=r.slice(1,-1).split`,`,r[0]>"]"&&eval(`i=a[0],l=a[1],n=a[2];for(a=[];n>0?i<=+l:i>=+l;i-=-n)a.push(i)`),"x")),a?a.map(n=>f(x.replace("x",n))).join``:x+` = ${r=eval(x),r<1/0?r:NaN}
`)
```

```
<input type="text" id="input" value="4.4 / [1,2.2] + {0,2,1}" />
<button onclick="result.textContent=f(input.value)">Go</button>
<pre id="result"></pre>
```

# Answer
> 4 votes
# Haskell, ~~474~~ 362 bytes

The function f takes a string as input and prints the results

```
g '+'=(+);g '-'=(-);g '*'=(*);g '/'=(\a b->a*b/b/b)
p[]=[]
p(o:x:y)=[(flip(g o)$n,' ':o:' ':show n)|n<-v]:p r where
    [f,e,s]=z;(z,h)=reads('[':y)!!0;(w,m)=reads(x:y)!!0;(v,r)|x=='['=(z,h)|x=='{'=([f,f+s..e],h)|True=([w],m)
h '}'=']';h x=x
d(a,b)=putStrLn.drop 3$foldl(++)""b++" = "++show(foldl(flip($))0a)
f t=mapM_(d.unzip)$sequence$p(filter(/=' ')$'+':map h t)

```

tests :

```
main=do
    f "4.4 / [1,2.2] + {0,2,1}"
    putStrLn""
    f "[1,2] / 0 + 5"
    putStrLn""
    f "{0,2,1} + {0,1,1}"

```

output:

```
4.4 / 1.0 + 0.0 = 4.4
4.4 / 1.0 + 1.0 = 5.4
4.4 / 1.0 + 2.0 = 6.4
4.4 / 2.2 + 0.0 = 2.0
4.4 / 2.2 + 1.0 = 3.0
4.4 / 2.2 + 2.0 = 4.0

1.0 / 0.0 + 5.0 = NaN
2.0 / 0.0 + 5.0 = NaN

0.0 + 0.0 = 0.0
0.0 + 1.0 = 1.0
1.0 + 0.0 = 1.0
1.0 + 1.0 = 2.0
2.0 + 0.0 = 2.0
2.0 + 1.0 = 3.0

```

# Answer
> 2 votes
# Python 3, 387 Bytes

```
def a(q,d=-1,f='',g=float,h=print):
 if any((c in q)for c in'[]{}'):
  for i,b in enumerate(q):
   if d!=-1:
    if b in'}]':
     e=f.split(",")
     if b=='}':
      r=g(e[0]);s=[]
      while r<=g(e[1]):s.append(str(r));r+=g(e[2])
      e[:]=s[:]
     [a(q[:d]+n+q[i+1:])for n in e];return
    f+=b
   if b in'[{':d=i
 else:
  h(q+" = ",end='')
  try:h(str(eval(q)))
  except:h("NaN")

```

You can test it with the following code:

```
tests=['3 * [3,2]', '{1,2,3}', '{0,2,1} + {0,1,1}',
       '6/[2,3]', '{1.5,2.5,0.5}', '3-{6,5,-1}',
       '5/{-1,1,1}', '4.4 / [1,2.2] + {0,2,1}',
       '[1,2] / 0 + 5']

for n in tests:
    print(n)
    a(n)
    print()

```

Here is the code ungolfed:

```
def eval_statement(query):
    left_bracket_index = -1
    inside_bracket_content = ''
    if any((bracket in query) for bracket in '[]{}'):
        for i, character in enumerate(query):
            if left_bracket_index != -1:
                if character in '}]':
                    params = inside_bracket_content.split(",")
                    if character == '}':
                        value = float(params[0])
                        values = []
                        while value <= float(params[1]):
                            values.append(str(value))
                            value += float(params[2])
                        params[:] = values[:]
                    for param in params:
                        new_query = query[:left_bracket_index] + param + query[i + 1:]
                        eval_statement(new_query)
                    return
                inside_bracket_content += character
            if character in '[{':
                left_bracket_index = i
    else:
        print(query + " = ", end='')
        try:
            print(str(eval(query)))
        except:
            print("NaN")

```

It works by finding the first set of brackets of any type, and then looping through all the values inside it, by replacing the brackets and its contents with the value and running the method recursively. It uses `eval` once there are no brackets in the line. It returns `NaN` if there is an exception running `eval`.

# Answer
> 1 votes
# ~~Dyalog APL, 164 bytes~~

This answer does not follow the updated requirements, and is therefore non-competing:

```
{n←⊂'NaN'
R←{+\b,s/⍨⌊((2⊃⍵)-b←⊃⍵)÷s←⊃⌽⍵}
D←{0::n⋄⍺×÷⍵}
↑(∊¨(,⍎'[-+×D]'⎕R','⊢e),¨¨⊂('[-+×÷]'⎕S'\0'⊢⍵),⊂'='),¨,⍎e←'{' '}' '\[' ']' '÷' '[-+×]'⎕R'(R ' ')' '(' ')' '∘.D ' '∘.{0::n⋄⍺\0⍵}'⊢⍵}

```

It uses regexes to change the given expression into the corresponding APL (and all operators are modified to implement `NaN`) and to extract the operators. It substitutes all operators with catenation and executes the expression to obtain the final input numbers. It then weaves it all together to get the final output.

Preserves the order of evaluation of APL (strict right-to-left).

Handles parentheses correctly.

Test cases (with added parentheses to force math-like order of execution):

```
      f '3 × [3,2]'
3 × 3 = 9
3 × 2 = 6
      f '{1,2,3}'
1 = 1
      f '{0,2,1} + {0,1,1}'
0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 + 1 = 2
2 + 0 = 2
2 + 1 = 3
      f '6÷[2,3]'
6 ÷ 2 = 3
6 ÷ 3 = 2
      f '{1.5,2.5,0.5}'
1.5 = 1.5
2   = 2
2.5 = 2.5
      f '3-{6,5,¯1}'
3 - 6 = ¯3
3 - 5 = ¯2
      f '5÷{¯1,1,1}'
5 ÷ ¯1 =  ¯5
5 ÷  0 = NaN
5 ÷  1 =   5
      f '(4.4 ÷ [1,2.2]) + {0,2,1}'
4.4 ÷ 1   + 0 = 4.4
4.4 ÷ 1   + 1 = 5.4
4.4 ÷ 1   + 2 = 6.4
4.4 ÷ 2.2 + 0 = 2
4.4 ÷ 2.2 + 1 = 3
4.4 ÷ 2.2 + 2 = 4
      f '([1,2] ÷ 0) + 5'
1 ÷ 0 + 5 = NaN
2 ÷ 0 + 5 = NaN

```

# Answer
> 1 votes
# Java, 874 bytes

```
void E(String s)throws Exception{int i=0;String t;List<String[]>z=new ArrayList<>();List<String>x=new ArrayList<>(),y=new ArrayList<>();for(String k:s.split(" "))t+=" "+(k.matches("[0-9]+")?"["+k+"]":k);for(String k:t.split(" "))s+=" "+(k.matches("\\{[^\\}]+\\}")?"["+R(k)+"]":k);for(String k:s.split(" "))t+=" "+(k.matches("\\[[^\\]]+\\]")?"$"+(i+=z.add(k.replaceAll("[\\[\\]]","").split(","))):k);x.add(t.substring(1));while (i-->0){y.clear();for(String e:x)for(String l:z.get(i))y.add(e.replace("$"+i,l));x.clear();x.addAll(y);}for(String e:x)System.out.println(e+"="+new javax.script.ScriptEngineManager().getEngineByName("JavaScript").eval(e).replace("Infinity","NaN"));}
String R(String t){String y="",[]s=t.replaceAll("[\\{\\}]","").split(",");int i=I(s[0]);y+="["+i;while ((i+=I(s[2]))<=I(s[1]))y+=","+i;y+="]";return y;}
int I(String t){return Integer.parseInt(t);}

```

---

**Detailed** Try Here

```
import java.util.*;
import java.lang.*;
import java.io.*;

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;

class Ideone
{
    // single : x -> [x]
    public static String expandSingle (String input)
    {
        String out = "";
        for (String str : input.split(" "))
        {
            out += " ";
            if(str.matches("[0-9]+"))
            {
                out += "["+str+"]";
            }
            else
            {
                out += str;
            }
        }
        return out.substring(1);
    }

    // range : {start,end,step} -> [x,..,y]
    public static String expandRange (String input)
    {
        String out = "";
        int a,b,c;
        int i=0;
        for (String str : input.split(" "))
        {
            out += " ";
            if(str.matches("\\{[0-9]+,[0-9]+,[0-9]+\\}"))
            {
                str = str.replaceAll("[\\{\\}]","");
                a = Integer.parseInt(str.split(",")[0]);
                b = Integer.parseInt(str.split(",")[1]);
                c = Integer.parseInt(str.split(",")[2]);

                out += "["+a;
                while ((a+=c) <= b) out += ","+a;
                out += "]";
            }
            else
            {
                out += str;
            }
        }
        return out.substring(1);
    }

    public static void main (String[] args) throws java.lang.Exception
    {
        String input = "3 * [3,2] + {0,2,1}";
        System.out.println(" input = "+input);
        input = expandSingle(input);
        input = expandRange(input);
        System.out.println(" expand = "+input);
        evaluate(input);
    }

    public static void evaluate (String input) throws java.lang.Exception
    {
        int i = 0;
        String t = "";
        ArrayList<String[]> set = new ArrayList<String[]>();
        ArrayList<String> in = new ArrayList<String>();
        ArrayList<String> out = new ArrayList<String>();

        // map sets
        for (String str : input.split(" "))
        {
            t += " ";
            if(str.matches("\\[.+\\]"))
            {
                str = str.replaceAll("[\\[\\]]","");
                set.add(str.split(","));
                t+= "$"+i;
                i++;
            }
            else t+=str;
        }
        in.add(t.substring(1));

        // generate expressions
        while (i-->0)
        {
            out.clear();
            for (String exp : in)
            {
                for (String sub : set.get(i))
                {
                    out.add(exp.replace("$"+i,sub));
                }
            }
            in.clear();
            in.addAll(out);
        }

        ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngine engine = mgr.getEngineByName("JavaScript");

        // print expressions
        for (String exp : in)
        {
            System.out.println(" "+exp+" = "+engine.eval(exp).replace("Infinity","NaN"));
        }
    }
}

```

---
Tags: code-golf, math
---


title: A loose spellchecker

text:
# Question
Title: A loose spellchecker
John Doe used to be one of the fastest QWERTY keyboard typists in the world, but a recent head injury caused by a stampeding herd of downgoats has critically hampered his ability to type accurately. In a desperate effort to retain his reputation as a typing prodigy, he has tasked us with the creation of a spellchecker - well, sort of. This spellchecker's rigged so that John Doe can worry less about accuracy and more about speed.

# Challenge

Here's the keyboard you'll be using. **NOTE: non-spacebar keys are separated by 2 spaces, with the un`shift`ed key followed by the `shift`ed key.**

```
`~   1!  2@  3#  4$  5%  6^  7&  8*  9(  0)  -_  =+
Tab  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  [{  ]}  \|
     aA  sS  dD  fF  gG  hH  jJ  kK  lL  ;:  '"  enter
     zZ  xX  cC  vV  bB  nN  mM  ,<  .>  /?
             [    SPACEBAR    ]

```

Notice how I have arranged the keys to line up properly. This is crucial for this challenge to work.

Write a full program/function that, given 2 strings of equal length containing only characters from the above keyboard, outputs a truthy/falsy value according to the following:

---

If all characters' keys are at most 1 away (horizontally, vertically, or diagonally) from the characters' keys at the same index in string 2, then output truthily.

* Example using `a`: Any characters in `aAqQsSzZwWxX` or `\t` (tab key) would return truthily.
* Special cases: `\n` (enter key) would return truthily for any character in `[{]}\|'"` or `\n`. Spaces (spacebar key) would return truthily for any character in `xXcCvVbBnNmM,<` or spaces.

Otherwise, output falsily.

**Note: Tabs and newlines will be actual representations instead of their escaped equivalents (`\t` and `\n`).**

---

This is ; shortest code wins.

# Example test cases

```
String1     String2        Output
---------------------------------
asdf        QWeR        => true
cat         gsl         => false
12345       qWeRty      => true
John Doe    Jonh Deo    => false

```

# Answer
# JavaScript (ES6), 287 bytes

```
(a,b)=>[...a].map((l,i)=>{p=k[g="indexOf"](l);q=k[g](o=b[i]);r=r?l==s|o==s?~m[g](l)&&~m[g](o):(x=(p%28/2|0)-(q%28/2|0))<2&x>-2&(y=(p/28|0)-(q/28|0))<2&y>-2:0},r=k=`\`~1!2@3#4$5%6^7&8*9(0)-_=+  \t qQwWeErRtTyYuUiIoOpP[{]}\\|  aAsSdDfFgGhHjJkKlL;:'"
     zZ${m="xXcCvVbBnNmM,<"}.>/?`,m+=s=" ")|r

```

## Explanation

Returns `1` for true and `0` for false.

Note that the `\t` should be a literal tab character.

```
(a,b)=>
  [...a].map((l,i)=>{               // for each character l at index i in word A
      p=k[g="indexOf"](l);          // p = index of l in k
      q=k[g](o=b[i]);               // o = letter in word B, q = index of o in k
      r=r?                          // if r
        l==s|o==s?                  // if l or o is a space
          ~m[g](l)&&~m[g](o)        // check the space-matching characters for l and o
        :
          (x=(p%28/2|0)-(q%28/2|0)) // X distance between letters A and B
            <2&x>-2&                // if distance is 2 or greater, r = 0
          (y=(p/28|0)-(q/28|0))     // Y distance between letters A and B
            <2&y>-2                 // if distance is 2 or greater, r = 0
      :0                            // do nothing if r == 0
    },
    r=                              // r = result

    // Keyboard string, each row is 28 characters long, using spaces as padding
    k=`\`~1!2@3#4$5%6^7&8*9(0)-_=+  \t qQwWeErRtTyYuUiIoOpP[{]}\\|  aAsSdDfFgGhHjJkKlL;:'"
     zZ${m="xXcCvVbBnNmM,<"}.>/?`,

    m+=                             // m = list of characters that are adjacent to space
    s=" "                           // add space to the list, s = space character
  )
  |r                                // return r

```

## Test

```
var solution = (a,b)=>[...a].map((l,i)=>{p=k[g="indexOf"](l);q=k[g](o=b[i]);r=r?l==s|o==s?~m[g](l)&&~m[g](o):(x=(p%28/2|0)-(q%28/2|0))<2&x>-2&(y=(p/28|0)-(q/28|0))<2&y>-2:0},r=k=`\`~1!2@3#4$5%6^7&8*9(0)-_=+  \t qQwWeErRtTyYuUiIoOpP[{]}\\|  aAsSdDfFgGhHjJkKlL;:'"
     zZ${m="xXcCvVbBnNmM,<"}.>/?`,m+=s=" ")|r
```

```
A = <input type="text" id="A" value="John Doe" /><br />
B = <input type="text" id="B" value="Jonh Deo" /><br />
<button onclick="result.textContent=solution(A.value,B.value)">Go</button>
<pre id="result"></pre>
```
> 1 votes

---
Tags: code-golf, keyboard
---


# Question
Title: Find the line guaranteed by Sylvester-Gallai
The Sylvester-Gallai theorem says: Suppose you have a finite list of points in the plane. Suppose further that not all of those points are collinear (lie in a single line). Then there is some line containing precisely two of the points. (That is, there's some line on which two of the points lie, but not more than two.)

You task is to find such a line. Note that more than one exists; you need to find one.

## Input:

A bunch of points denoted by their Cartesian coordinates. You may assume the coordinates are nonnegative integers, if you like. The string `(1,2),(0,4),(5,6)` and the list `1`, `2`, `0`, `4`, `5`, `6` and other formats are fine, and can be function parameters or read from STDIN or whatever.

If you prefer, allow also radical-root input (with positive-integer index). Then, each point will be represented by four numbers: the index and radicand of the abscissa, and the index and radicand of the ordinate. A rational number will be represented with index `1`. Again, the input can be like `((1,2),(3,4)),((6,7),(8,9)),((2,3),(4,5))` or like `1`, `2`, `3`, `4`, `6`, `7`, `8`, `9`, `2`, `3`, `4`, `5`, or what-have-you. You may assume that the radicand is a nonnegative integer.

You may assume the points are distinct from one another and are not all collinear (and thus, in particular, that there are more than two points).

## Output:

A line guaranteed by Sylvester-Gallai. This can be presented in any Cartesian-based form that completely specifies the line and allows people to visualize it. (I expect that answers will typically use either the line's slope and a point on it or two points on the line.)

## Scoring:

This is a popularity contest. The answer with the greatest number of net votes after about a week will get the checkmark. Everyone can vote at will, obviously, but I, personally, will bear in mind at least these factors: ingenuity of the solution (including avoidance of the brute-force method), explanation of the code, ability to accept radical-root input, and simplicity of the code (in flop count / runtime).

# Answer
> 4 votes
## Python 2, not golfed

Sure, they say there's a worst case O(n\*log(n)) algorithm, but who cares about the worst case? It's the average case we usually care about, and this simple random algorithm runs in expected linear time on arbitrary inputs!

(By comparison, the deterministic brute force algorithm can be fed carefully constructed inputs to force it to run in quadratic time at least.)

```
import random,math
def radical_to_normal(x,y): return (x[1]**(1./x[0]),y[1]**(1./y[0]))

def distance_to_line(p1,p2,p3):
 dx = p2[0] - p1[0]
 dy = p2[1] - p1[1]
 return abs(dy*p3[0] + dx*p3[1] + p2[0]*p1[1] - p2[1]*p1[0]) / math.sqrt(dy*dy + dx*dx)

points = input() #input as list of pairs
c = True
while c:
    c = False
    p1,p2 = random.sample(set(points), 2)
    for p3 in points:
        if distance_to_line(radical_to_normal(*p1), radical_to_normal(*p2), radical_to_normal(*p3)) < 0.00001:
            c = True
print p1,p2

```

Example run:

```
➤ python sylvester.py
[((1,0),(1,0)),((1,1),(1,0)),((1,2),(1,0)),((1,0),(1,1)),((1,1),(1,1)),((1,2),(1,1)),((1,0),(1,2)),((1,1),(1,2)),((1,2),(1,2))]
((1, 2), (1, 2)) ((1, 0), (1, 1))

```

## How it works

It's been proved (Csima and Sawyer 1993) that roughly 6/13 of all lines in any set are ordinary (only involve 2 points from the set) except when n=7. As the number of points goes to infinity, the lower bound goes to 1/2 of the lines (Green and Tao 2013). Therefore, we expect to have to test around 2-3 pairs of points on average before finding an ordinary line *if* we sample pairs of points at random.

This simple program just selects a random pair of points, then checks the distance from the line they form to a third point, which ranges over all points in the set. All three points are converted from radical root form to floats by `radical_to_normal()` before the distance is calculated by `distance_to_line()`. If the distance is below a threshold (indicating they are collinear), we set a sentinel to try again. Until every point tested passes above the threshold, we try, try again. (This threshold could be made much smaller and still work, of course.)

Since we test an expected constant number of point pairs, and we test n points for each pair, the algorithm runs in expected time O(n).

# Answer
> 0 votes
# Mathematica, 73 bytes

```
Cases[#~Subsets~{2},p_/;InfiniteLine@p~RegionMember~#~Count~True==2,1,1]&

```

---

**Test Case:**

```
%[{{0,0},{1,1},{3,2},{3,3},{6,4},{4,5}}]
(* {{{0,0},{4,5}}} *)

```

---

**Explanations:**

`#~Subsets~{2}` gives all pairs of points; `InfiniteLine@p~RegionMember~#~Count~True==2` tests whether there are exactly two points intersect the infinite line given by a pair of points `p`; `Cases[..., ..., 1, 1]` gives the first pair of points that meet the condition.

Mathematica naturally accepts numbers like `3/5`, `Pi`, `Sqrt[2]`, etc, and gives accurate results as long as the inputs are accurate.

---
Tags: popularity-contest, geometry
---


title: Inverse symbolic calculator

text:
# Question
Title: Inverse symbolic calculator
This challenge is based on the idea of Plouffle's Inverter.

Write a program in any language that does the following:

* Takes as input a non-negative rational number `X` written in decimal, for example 34.147425.
* Returns a mathematical expression using only non-negative integers, whitespace, parentheses, and the following binary operators:

+ Addition `+`
    + Subtraction `-`
    + Multiplication `*`
    + Division `/`
    + Exponentiation `^`

The expression should evaluate to `X`, or at least agree with all the digits of `X`. To continue the example, a correct output could be `13 + 20^(5/4) / 2`, since 13 + 20^(5/4) / 2 = 34.1474252688...
* Output may optionally be written in Polish notation (prefix) or reverse Polish notation (postfix), i.e. `+ 13 / ^ 20 / 5 4 2` is fine.

The program is subject to the following retrictions:

* Standard loopholes are forbidden! In particular, the program cannot read any external lookup table.
* The source code of the program must be shorten than 1024 characters.

**The program with the lowest average compression ratio will win.**

To determine your average compression ratio, you can to use the following Python script, or write your own equivalent program. Here is the list of 1000 random numbers.

```
import random

def f(x):
    # edit this function so that it will return
    # the output of your program given x as input
    return "1 + 1"

random.seed(666)

S = 1000 # number of samples

t = 0.0

for n in xrange(0, S):
    # pick a random decimal number
    x = random.uniform(0, 1000)

    # compute the compression ratio
    # length of output / length of input
    r = len(f(x).translate(None, " +-*/^()")) / float(len(str(x).translate(None, ".")))
    t += r

print "Your average compression ratio is:", t / S

```

Good luck!

**NOTES:**

* Whitespaces in the output are not mandatory. Strings like `1+1`, `1 +2`, or `1 + 2`, are all okay. Indeed, the script to compute the score does not count whitespaces and parenthesis in the length of the output. However, note that the use of whitespaces is necessary if you choose Polish or reverse Polish notation.
* Regarding the usual infix notation, the precedence rules are the following: first all exponentiation (`^`), then all divisions (`/`), then all multiplications (`*`), then all additions (`+`) and all subtractions (`-`). But I do not know how much this could matter, since you can use parentheses.
* A way to edit the function `f` in the script above can be the following, however I think that it depends on your operating system; on GNU/Linux it works. Name your program "inverter" (or "inverter.exe") and place it in the same directory as the Python script. Your program should get `X` as the first argument of command line and return the expression in STDOUT. Then edit `f` as follows:

```
import os
def f(x):
    return os.popen("./inverter " + str(x)).read()

```

**EDIT:** As a consequence of the comment of Thomas Kwa, now the operators do not contribute to the length of the expression. The challenge should be more "challenging".

# Answer
> 3 votes
## Haskell, 1.08404005439

```
import System.Environment
import Data.Ratio
import Data.Lists

main = do
   arg <- fmap head getArgs
   let number = read (arg ++ "5")
   let (_,_:decs) = span (/= '.') arg
   let acc = (read $ "0." ++ (decs >> "0") ++ "4999") :: Double
   putStr $ replace " % " "/" $ show $ approxRational number acc

```

This uses the `approxRational` function which converts a floating point number to a fraction with a accuracy of a given epsilon. It simply returns this fraction. As Haskell prints rationals with a `%` in-between, we have to replace it with the division sign `/`.

The accuracy parameter is calculated from the input number. We have to take into account that all the digits have to match, so `4.39` is fine for `4.3` but `4.29` isn't. I append a `5` to the number and the accuracy is a `4999` at the same decimal place as the appended `5`, e.g.

```
12.347       -- input number
12.3475      -- append 5
 0.0004999   -- accuracy epsilon for the "approxRational" function.

```

E.g. `34.147425` -\> `43777/1282`.

Edit: the rules for accuracy have changed. The test case includes numbers with up to 11 decimal places and all have to match.

Edit II: it seems that the provides Python script doesn't strip off trailing newlines, so I've changed from `putStrLn` to `putStr`.

Edit III: again, new scoring rules

# Answer
> 2 votes
# Mathematica, ~~1.1012~~ 1.10976107226107

```
Rationalize[# + 5 (a = 10^(Floor@Log10@# - Length[First@RealDigits@# //. {a___, 0} :> {a}])), 5 a - 1*^-4 a]~ToString~InputForm &

```

So far, this has the lowest score! Gives the rational with the smallest denominator given the digits. (Sorry for the unreadability, forgot that this wasn't a golf contest for a minute.) Some testing:

```
In[1]:= f=Rationalize[#+5(a=10^(Floor@Log10@#-Length[First@RealDigits@#//.{a___,0}:>{a}])),5a-1*^-4a]~ToString~InputForm&;

In[2]:= f[811.359484104]

Out[2]= 9876679/12173

In[3]:= f[0.000000001]

Out[3]= 1/666666666

In[4]:= f[999.999999999]

Out[4]= 2000021150999/2000021151

```

# Answer
> 2 votes
# Python, 1.25927791772

I'm surprised no one else has tried the obvious approach, which incurs about 26% overhead:

```
from decimal import *
def simplify(numstr):
    numdec = Decimal(numstr)
    digits = -(numdec.as_tuple().exponent)
    num = float(numstr)
    return '{0:.0f}'.format(num * 10**digits) + '/10^' + str(digits)

```

This just converts `XX.XXXX` into `XXXXXX/10^4` and so on. For the majority of test numbers, this means converting 12 digits (and an uncounted decimal point) to the same 12 digits plus three more (plus two uncounted symbols).

# Answer
> 0 votes
# JavaScript 1.7056771894771656

Very simple, very bad score

```
F=x=>([x,d]=x.split`.`,n=+(x+d),d=+d.replace(/./g,9)+1,G=(a,b)=>b?G(b,a%b):a,g=G(n,d),(n/g)+'/'+(d/g))

test=[456.119648977, 903.32315398, 434.375496831, 500.626690792, 811.359484104,
553.673742554, 712.174768248, 123.142093787, 814.759762152, 385.493673216,
629.109959804, 891.825687728, 988.817827772, 16.7651557543, 967.455933006,
99.3802569984, 681.552992408, 169.770898456, 921.658967707, 610.512640655,
420.065644152, 702.514151372, 517.04720252, 86.3589856368, 960.117250449,
311.152728003, 620.240077706, 130.232920047, 901.22564153, 528.511688187,
50.841278105, 737.146071519, 836.88270257, 13.9544843156, 45.8723706867,
760.14443626, 256.035110545, 460.972156302, 217.514875811, 34.4165446011,
426.209854826, 500.979753237, 930.071200996, 751.301967463, 817.525354878,
918.861794618, 794.520266221, 531.896652685, 419.295924811, 927.526963939,
989.027382734, 82.1589263516, 965.904769963, 708.295178015, 778.541588483,
410.404428666, 894.612613172, 470.045387404, 460.773246884, 505.524899467,
451.852274382, 417.910824093, 883.45180574, 319.767238241, 544.794416784,
346.361844704, 122.300743514, 517.293385872, 748.134450425, 589.547392631,
870.937945528, 465.607198253, 379.697188157, 215.095671553, 471.696590273,
544.827425571, 883.01895272, 514.893297677, 703.800591, 788.816870867,
777.433484884, 990.615076538, 925.473132794, 494.964321255, 911.643885633,
103.244050895, 425.938382631, 421.075783639, 363.155392963, 301.617712632,
268.237096551, 42.0971441114, 252.071029659, 260.398845137, 433.781658026,
278.550969539, 446.456847155, 466.145132666, 23.1267325005, 92.2303701531,
792.994090972, 100.482658881, 796.600758817, 786.019664003, 328.859998399,
390.221668208, 750.32581915, 332.277362524, 983.205082197, 862.001172096,
823.825060923, 662.455639665, 926.337262367, 618.446017944, 696.465793349,
408.095136772, 519.31659792, 928.091368548, 177.367743543, 980.822594006,
401.832552937, 66.1163636071, 127.511709579, 291.85194129, 11.338995907,
880.568902788, 982.945394792, 491.753920356, 222.011915866, 317.023389252,
601.694693495, 871.340895438, 427.621115915, 886.273120812, 345.688431619,
248.992214068, 738.874584632, 109.03516681, 146.362341902, 447.713463802,
600.947018155, 415.419601291, 369.549014288, 141.697677152, 895.502232931,
528.201404793, 673.817459041, 215.852364841, 164.552047867, 764.085838441,
323.70504093, 197.868519457, 759.91813327, 369.341528152, 768.793424447,
111.674153727, 495.99248701, 363.669738825, 596.082713332, 747.205484326,
666.879146337, 102.908405893, 424.113319661, 476.379228696, 971.353959219,
162.634464034, 761.838583493, 767.799964665, 347.294217881, 353.760366385,
230.905221575, 125.898250349, 565.850510939, 667.61204275, 196.449923318,
279.792505368, 279.034332146, 533.902967966, 57.688797172, 153.08128158,
821.993175733, 982.886617074, 433.447389936, 29.0911289168, 442.422057169,
804.518563086, 500.73307383, 948.932673563, 723.030013363, 572.092408062,
853.660849797, 481.331513905, 942.064561235, 42.4709711072, 982.87325027,
352.171583912, 238.247057259, 823.238147233, 526.013997729, 644.51102393,
366.71793217, 933.49508788, 903.534625763, 857.169528071, 735.780465845,
378.732263357, 12.1875971069, 964.370964223, 419.654315024, 705.414457347,
353.953487281, 501.657967991, 849.706011343, 713.414932699, 827.420809946,
596.719004174, 609.780183857, 826.546581587, 76.33513551, 0.500492073649,
627.694684485, 186.236492637, 360.200893605, 478.625892592, 229.111877611,
423.754891888, 657.973373515, 16.9761882463, 974.491769915, 945.864753785,
237.454051339, 179.687469205, 418.658590265, 714.833543375, 318.816023475,
650.727666516, 488.596054138, 987.542619517, 216.006047902, 80.7125255243,
144.181653533, 266.522883823, 818.574355104, 600.21171237, 895.307289865,
198.329664663, 124.824876993, 31.1227116403, 541.348603643, 542.257190363,
304.231517157, 506.706000025, 84.9413478067, 170.491409724, 229.013799764,
671.014301245, 87.1441069227, 763.676724963, 742.639944243, 435.559778934,
383.882521911, 238.741657776, 647.17907848, 927.512981306, 549.612975568,
791.443454295, 701.809936899, 987.551368536, 91.3122813408, 398.587619734,
847.240295481, 470.53644512, 507.410113063, 540.35838629, 637.883207888,
982.322584309, 975.975221911, 371.493982019, 172.638439006, 747.126873375,
99.5418242164, 309.903703204, 640.628684948, 314.750618166, 146.000991772,
384.388581648, 217.815818267, 733.571499911, 690.506791178, 945.671862182,
344.854300466, 66.9720187046, 600.727439672, 98.4760964868, 295.60483304,
478.855074245, 490.351187811, 479.533769337, 239.205093033, 58.7686847649,
375.442162104, 615.561415277, 974.347539912, 743.935932659, 210.319831557,
782.442881822, 556.123534411, 774.571029531, 821.094541585, 782.478179678,
123.630035193, 652.088033798, 753.122074115, 303.840694329, 449.088557671,
38.4843483532, 173.031570335, 728.973326841, 226.816627623, 119.472479023,
705.899011665, 927.865200825, 157.998809157, 327.490515863, 225.137067487,
501.556087254, 167.031923234, 396.975128016, 826.305341676, 396.340544863,
569.58630546, 694.788762272, 10.1343501944, 369.36109683, 29.8034453658,
916.970188353, 985.814850566, 888.359275561, 689.939392935, 409.116566134,
144.938228502, 67.8210674843, 870.61549803, 563.639796984, 431.618386108,
145.691380363, 350.505911146, 326.638836654, 708.160936271, 345.738257395,
159.932627655, 311.885663889, 229.603462168, 110.746858295, 517.566252532,
231.2683822, 908.329966697, 999.286952896, 700.486300449, 532.543272168,
548.536320153, 248.586068291, 844.156717745, 477.281959996, 964.072712855,
157.863146561, 919.917761996, 187.741733233, 358.474587832, 541.364663045,
297.862474812, 673.876495999, 641.468684483, 934.366789232, 112.750864631,
179.36727691, 744.421362119, 954.914513373, 356.362877284, 642.423557253,
835.156704382, 145.847575914, 917.085464611, 633.00944503, 4.20412765537,
577.177004175, 774.63403371, 846.937269117, 978.134451441, 927.806763324,
3.39763102303, 650.528163199, 347.525631206, 378.956292306, 266.22945414,
175.085055263, 571.539823838, 274.670508282, 835.348780918, 190.612093018,
425.355323169, 283.050471535, 573.262462068, 236.809923974, 86.5812138421,
442.645729259, 376.598156438, 412.17611326, 575.13654395, 76.4906160271,
382.261334337, 419.108062252, 413.347694426, 726.1697083, 738.059837008,
228.479265313, 982.210601477, 693.205052764, 788.820483643, 279.491316277,
381.050856949, 914.836538216, 369.451591691, 828.975002455, 33.0866822761,
552.943575842, 229.194581446, 900.603947989, 697.081349116, 38.8501269177,
599.81038281, 199.242914298, 565.383604483, 241.671424615, 874.199638779,
294.933677019, 238.713921761, 953.886254575, 126.3147347, 156.308580451,
1.01666626965, 410.067483484, 969.052527031, 184.927913357, 282.530928636,
204.745328524, 450.670433109, 129.119772077, 581.256246505, 6.84233762299,
39.4666067908, 865.975624765, 868.401636982, 114.207339514, 921.542812579,
435.593193085, 346.934279797, 830.059520451, 691.952980275, 694.258623119,
548.775134898, 527.057955887, 267.64250387, 113.091700858, 210.713307935,
253.707632265, 832.083850441, 455.161145588, 403.528402677, 237.983049672,
903.782609365, 314.331975332, 209.862002009, 488.057537383, 905.587478495,
929.797161232, 325.793664626, 734.098176437, 519.087164488, 555.076580313,
97.8973027155, 260.92615898, 391.460005616, 187.462694014, 660.460370626,
861.783280209, 751.657352012, 528.280341385, 943.741294674, 204.705877292,
106.65265656, 17.8070044565, 233.101412197, 38.2613365534, 729.385921979,
773.529715946, 429.882870272, 166.782428109, 738.061383178, 381.289974545,
425.98872381, 405.120420988, 672.370449304, 276.696982879, 640.620718977,
244.652935713, 43.3611372718, 611.721720179, 552.336391617, 939.435275549,
337.333914132, 88.3768763311, 537.456873711, 98.6468535441, 601.024140128,
526.374477437, 959.339713851, 794.438445711, 419.365144317, 128.425263651,
894.306756225, 750.689349267, 849.804073407, 144.580034264, 5.21870382078,
316.954557791, 258.037070914, 907.185890899, 821.078874769, 73.0065239329,
902.397997543, 623.811378865, 278.742785334, 546.742289504, 306.338798014,
624.510083572, 278.778694986, 992.433419109, 568.791129496, 800.987198104,
817.781503455, 364.391142069, 229.768701593, 791.500313449, 523.97492671,
711.79222697, 841.514367793, 811.043873744, 312.112640331, 344.686366808,
362.852877349, 908.102021975, 77.1500991776, 383.192419609, 686.951731951,
220.529025627, 867.530056756, 14.3366282672, 408.594160445, 123.165786631,
998.59134116, 548.326927924, 94.1928597561, 324.065711084, 731.488189617,
665.464202995, 306.278211631, 986.173950386, 627.219661146, 333.954277825,
90.2956353646, 162.227112949, 272.511457828, 857.528739452, 503.843643462,
576.629152535, 548.024554676, 363.491120268, 679.874538441, 583.700940158,
106.952792329, 9.38392100562, 338.353858169, 293.571162077, 804.681145319,
767.462050744, 313.643862301, 468.190192547, 572.949085984, 350.221796616,
917.105455473, 303.54853149, 391.390619956, 504.247647998, 93.0135480388,
246.512166315, 908.97228941, 943.218403856, 530.309445245, 309.754887232,
959.789201543, 970.486542083, 797.580736004, 290.319550119, 846.108212188,
532.653666441, 887.339176163, 679.691675058, 912.533817736, 920.067525894,
222.511534133, 96.2743176283, 21.4898199044, 77.2132479765, 371.345880832,
436.959444929, 215.804186286, 399.231434773, 621.793520068, 670.184752989,
898.150427875, 223.481192922, 886.318270113, 516.799097006, 533.999918536,
713.480918784, 917.832970718, 372.788549636, 628.966711322, 944.179767515,
192.101163486, 343.997422161, 804.100009349, 931.645390583, 990.171180084,
260.766724798, 785.681499223, 356.704428677, 700.517830816, 951.584623525,
144.084686297, 259.528412476, 171.745260869, 139.015277926, 901.447521593,
620.501210347, 151.032781338, 46.1159165911, 425.230998623, 894.613060967,
625.179508617, 242.868974022, 106.982050541, 301.464135508, 573.158784529,
688.278622585, 464.999428923, 322.662480912, 110.118666284, 731.557589997,
946.121567036, 495.536592777, 721.786554826, 401.204812967, 523.199107158,
941.414041302, 13.1534875549, 156.596310513, 983.985066957, 371.429892366,
597.927750948, 983.992168593, 170.977999856, 83.6807794877, 817.971626168,
516.088416242, 827.937736139, 859.209288785, 615.315584986, 609.792111637,
554.693516004, 470.967675734, 223.237818744, 990.385531141, 530.824138102,
909.365555497, 994.864631519, 997.447332309, 328.212731713, 307.035914722,
409.123485776, 799.130975525, 967.234526581, 959.671441584, 353.229298604,
420.982728285, 76.7863969552, 28.5449571984, 210.265549753, 913.543941547,
315.091741118, 662.094750123, 852.203603892, 298.207293217, 509.30012338,
65.7679645109, 621.200794815, 935.510670259, 779.330025526, 937.283929747,
756.173490123, 733.792396159, 795.211149457, 302.088313881, 570.641269144,
757.135463505, 242.60845981, 457.593727034, 225.360079221, 142.221548109,
17.6336964488, 360.261380451, 623.475218825, 692.670820913, 584.185971173,
662.861929515, 276.807298644, 480.122225367, 954.608081636, 627.928577217,
459.835351987, 485.168643598, 793.612119132, 654.855590208, 271.958933288,
969.652698005, 976.785064283, 505.116414306, 797.184208528, 628.943525947,
959.160096155, 663.113680213, 768.371354051, 590.4585491, 773.296754989,
407.351603593, 88.0630070991, 905.529072694, 340.59794601, 439.12099902,
233.540790202, 364.088450076, 470.123174021, 102.448882161, 608.789225571,
392.768415134, 713.100614552, 209.2003898, 62.2154487033, 372.921756097,
492.623365519, 581.128110129, 820.570542768, 339.686321984, 713.824072462,
999.045113081, 306.938298797, 184.480805204, 465.144186806, 753.870865996,
78.4248974773, 914.793550949, 952.526126809, 745.524994917, 138.306312094,
727.779875346, 561.393678162, 772.777064716, 72.7542234799, 504.766493657,
753.225048814, 171.848362302, 941.292665664, 441.751526079, 63.0349316166,
535.273783514, 629.040768898, 808.08324249, 457.787416804, 187.372504534,
418.1266562, 433.695070727, 776.092568964, 211.004041498, 740.766035298,
816.391594543, 458.991042003, 94.0308738235, 624.589391691, 118.430830788,
178.888039553, 905.16710481, 148.542033271, 962.242139722, 35.5229349814,
716.472840429, 587.99823034, 252.557765324, 37.8879245566, 399.689202524,
383.425506008, 464.748020898, 308.786698798, 583.669994119, 231.746308268,
524.76171028, 897.374397044, 577.218755662, 562.645278506, 434.940887118,
254.327344231, 540.874257344, 123.680835723, 539.503191151, 816.484752836,
961.415099734, 349.660216271, 596.159995894, 595.762432693, 955.539005194,
687.809440375, 571.725613886, 308.13021345, 617.471476595, 701.003582396,
3.96581420188, 185.987820184, 48.1246847598, 539.131050625, 989.571379915,
249.821643429, 725.895300104, 711.034103146, 74.8291260662, 721.572101122,
142.992636014, 419.591421178, 984.914852359, 36.7363617464, 133.19819475,
380.054235605, 692.83285665, 827.597995374, 995.818667532, 126.589103128,
682.800070236, 466.330036969, 302.143073837, 786.240218566, 299.551583986,
430.07770804, 483.534119703, 473.617334239, 1.64416431436, 953.126991927,
251.892147628, 366.320222366, 137.6878957, 287.000037146, 348.549654758,
55.6668003422, 65.1444653143, 810.336733005, 247.448273359, 514.541152359,
545.299341596, 740.254480746, 607.431747363, 176.075079982, 922.502042696,
585.799132666, 5.53670276888, 304.467968825, 298.915106192, 561.78882135,
42.5914472262, 486.800635021, 61.0833598622, 944.347739678, 668.746271709,
756.586266764, 408.787974993, 161.622855, 76.9222121123, 273.398447299,
224.158188706, 869.44674983, 58.3114312618, 490.559449132, 439.137943547,
816.959032357, 73.0577752895, 613.711059891, 899.395509193, 230.235211112,
651.089914878, 418.795635547, 873.424446884, 897.792771782, 704.102385815,
518.126528796, 545.099037865, 104.410545145, 416.115870896, 617.579630637,
333.700660761, 698.454752336, 323.794560581, 614.778464988, 978.982432433,
656.459219246, 311.387615291, 262.993283002, 98.703803798, 316.038737757,
511.251635007, 597.716611457, 837.873132231, 985.745340467, 653.714321915,
759.002380543, 257.908251778, 764.546995782, 336.260865935, 746.604123567,
640.209566004, 448.844970845, 925.255475065, 972.485574416, 47.0841050739,
231.133339622, 994.520385942, 766.591528041, 355.476025092, 325.525579517,
591.707824382, 302.51618806, 250.791496027, 325.751078168, 148.78604636,
488.176440838, 760.361648381, 213.189413642, 509.565395067, 284.468094856,
567.126065507, 828.024492382, 938.902419548, 141.420420877, 719.989392811,
854.189823836, 545.746745299, 713.177111859, 800.749418944, 217.781813549,
692.416094897, 703.129981045, 607.928079305, 876.072026145, 983.933471359,
824.755945781, 472.143208136, 22.2541577801, 640.071388089, 52.8148724127,
646.607940231, 228.870749952, 824.59255967, 20.4078078906, 211.860134988,
176.392620646, 786.744977859, 983.183973543, 738.585099683, 75.976724176,
49.4604753001, 628.2042889, 991.358549436, 526.125428702, 836.487360003,
216.533860839, 654.106395874, 65.4049854833, 858.352891393, 777.146190395,
630.588944701, 141.352770092, 501.454292251, 792.956685991, 709.053823609];

console.log=(...x)=>O.textContent+=x.join` `+`\n`

console.log(test.length)
var r=0
test.forEach(v=>{
  v=v+''; // to decimal string
  var x=F(v);
  check = v==eval(x)
  if (!check) console.log ("Error",v,x,eval(x));
  else
    // console.log(v,x),
    r+=x.length/v.length

});
console.log(r/1000)
```

```
<pre id=O></pre>
```

# Answer
> 0 votes
# Python, 1.9901028749

Continued fractions turn out to not be a serious contender, unfortunately.

```
from fractions import *
def simplify(numstr):
    frac = Fraction(numstr)
    terms = []
    while frac>0:
        terms.append(int(frac))
        frac -= int(frac)
        if frac > 0:
            frac = 1/frac
    for n in range(0,len(terms)):
        temp = 0
        for i in range(n,0,-1):
            temp = 1.0/(terms[i]+temp)
            # print i, terms[i], temp
        temp += terms[0]
        # print repr(temp)
        if repr(temp)[:len(numstr)] == numstr:
            break
    return '+1/('.join([str(x) for x in terms[:n+1]]) + ')' * n

```

examples:

```
141.352770092 141+1/(2+1/(1+1/(5+1/(20+1/(20+1/(1+1/(1)))))))
501.454292251 501+1/(2+1/(4+1/(1+1/(31+1/(1+1/(4+1/(1+1/(1+1/(2)))))))))
792.956685991 792+1/(1+1/(22+1/(11+1/(2+1/(6+1/(1+1/(2+1/(1+1/(2)))))))))
709.053823609 709+1/(18+1/(1+1/(1+1/(2+1/(1+1/(1+1/(1+1/(10+1/(58)))))))))

```

# Answer
> 0 votes
# Python, 1.10900874126

Actually evaluating the continued fractions in my previous answer yields the equivalent of @LegionMammal978 s Mathematic answer, which I think is the naive optimum. Doing better than this will require getting creative with representing the integers, possibly including searching for sub-optimal fractions to get to easier-to-represent integers.

```
from fractions import *
def simplify(numstr):
    frac = Fraction(numstr)
    terms = []
    while frac>0:
        terms.append(int(frac))
        frac -= int(frac)
        if frac > 0:
            frac = 1/frac
    for n in range(0,len(terms)):
        temp = Fraction(0)
        for i in range(n,0,-1):
            temp = Fraction(1)/Fraction(terms[i]+temp)
            # print i, terms[i], temp
        temp += terms[0]
        if repr(float(temp))[:len(numstr)] == numstr:
            break
    return str(temp.numerator) + '/' + str(temp.denominator)

```

examples:

```
141.352770092 == 1992650/14097
501.454292251 == 5041120/10053
792.956685991 == 33373961/42088
709.053823609 == 154592878/218027

```

---
Tags: code-challenge, math, number
---


# Question
Title: Predict whether a message will be starred or not in 50 bytes
Given an input of a string consisting of any message from our site chatroom taken from the list described and linked below, output either a truthy or a falsy value attempting to predict whether that message was starred or not in 50 bytes or less.

You may use any truthy or falsy values, but they must be identical (i.e. there should only be two possible outputs, one truthy and one falsy). The input will be given as raw HTML with newlines removed, and it may contain non-ASCII Unicode characters. If you require input in something other than UTF-8, please say so in your answer.

The winning submission to this challenge will be the one that predicts the highest percentage of chat messages correctly, out of the list linked below. If two given submissions have the same success rate, the shorter submission will win.

Please provide instructions for running your code on the entire set of messages and calculating the percentage correct. Ideally, this should be a bit of boilerplate code (not counted towards your 50 bytes) that loops through the positive test cases and outputs how many of them your code got correct and then does the same for the negative test cases. (The overall score can then be calculated manually via `(correctPositive + correctNegative) / totalMessages`.)

So that your code is reasonably testable, it must complete in 5 minutes or less for the entire list of chat messages on reasonable modern-day hardware.

The full list of chat messages can be found here, and it consists of the 1000 latest starred messages as truthy test cases and the 1000 latest unstarred messages as falsy test cases. Note that there are two files in the gist; scroll about halfway down for the unstarred messages.

# Answer
# Retina, 50 bytes, ~~71.8%~~ 72.15%

```
^.*([[CE;ಠ-ﭏ]|tar|ol|l.x|eo|a.u|pin|nu|o.f|"$)

```

Tried some regex golfing at @MartinBüttner's suggestion. This matches 704 starred messages and doesn't match 739 unstarred messages.

The `^.*( ... )` is to make sure that there is always either 0 or 1 match, since Retina outputs the number of matches by default. You can score the program on the input files by prepending `m`` for multiline mode, then running

```
Retina stars.retina < starred.txt

```

and likewise for `unstarred.txt`.

---

### Analysis / explanation

I generated the above snippets (and many more) using a program, then selected the ones I wanted manually. Here's some intuition as to why the above snippets work:

* `C`: Matches `PPCG`, `@CᴏɴᴏʀO'Bʀɪᴇɴ`
* `E`: Matches `@ETHproductions`, `@El'endiaStarman`
* `;`: Because the test cases are HTML, this matches `<` and `>`
* `ಠ-ﭏ`: Matches a range of Unicode characters, most prominently for `ಠ_ಠ` and `@Doorknob冰`
* `tar`: Matches variations of `star`, `@El'endiaStarman` (again) and also `gravatar` which appears in the oneboxes posted by new posts bots
* `ol`: Matches `rel="nofollow"` which is in a lot of links and oneboxes
* `l.x`: Matches `@AlexA.`, `@trichoplax`
* `eo`: Mainly matches `people`, but also three cases for `@Geobits`
* `a.u`: Mainly matches `graduation`, `status`, `feature` and `abuse`
* `pin`: Matches `ping` and words ending in `ping`. Also matches a few posts in a discussion about `pineapple`, as an example of overfitting.
* `nu`: Matches a mixed bag of words, the most common of which is `number`
* `o.f`: Matches `golf`, `conf(irm|use)`
* `"$`: Matches a double quote as a last character, e.g. `@phase He means "Jenga."`

The `[` is nothing special - I just had a character left over so I figured I could use it to match one more case.
> 29 votes

# Answer
# JavaScript ES6, 50 bytes, 71.10%

Correctly identifies 670 starred and 752 non-starred.

```
x=>/ .[DERv]|tar|a.u|l.x|<i|eo|ol|[C;ಠ]/.test(x)

```

Now across the 70% barrier, and beating everyone except Retina!

Returns `true` if the message contains any of these things:

* A word of which the second letter is `D`, `E`, `R`, or `v`;
* `tar` (usually `star`);
* `a` and `u` with one char in between;
* `l` and `x` with one char in between (usually `alex`);
* italic text;
* `eo` or `ol`;
* a `C`, a semicolon, or a .

Here's a few more fruitful matches that don't seem to be worth getting rid of others:

* `nf`
* `nu`
* `yp`
* `n.m`

This has been growing closer and closer to the Retina answer, but I have found most of the improvements on my own.

Test it out in the console of one of these pages: star texts, no-star texts

```
var r=document.body.textContent.replace(/\n<br/g,"<br").split("\n").slice(0,-1);
var s=r.filter(function(x){return/ .[DERv]|tar|a.u|l.x|<i|eo|ol|[C;ಠ]/.test(x)}).length;
console.log("Total:",r.length,"Matched:",s,"Not matched:",r.length-s);

```

---

Here's an alternate version. `/a/.test` is technically a function, but doesn't satisfy our criteria:

```
/ .[ERv]|a.u|l.x|<i|eo|yp|ol|nf|tar|[C;ÿ-ﬀ]/.test

```

This scores 71.90% (697 starred, 741 unstarred).

---

I've been running some analyses on the lists to see which regex groups match the most starred and the least unstarred posts. The analyses can be found in this Gist. So far, I've checked `aa` and `a.a` matches. `a.u` is down at around #50 with a score of 28, yet it's the most efficient match of its format...
> 18 votes

# Answer
# Pyth, 50 bytes, 67.9 %

```
0000000: 21 40 6a 43 22 03 91 5d d3 c3 84 d5 5c df 46 69 b5 9d  !@jC"..]....\.Fi..
0000012: 42 9a 75 fa 74 71 d9 c1 79 1d e7 5d fc 25 24 63 f8 bd  B.u.tq..y..].%$c..
0000024: 1d 53 45 14 d7 d3 31 66 5f e8 22 32 43 7a              .SE...1f_."2Cz

```

This hashes the input in one of 322 buckets and chooses the Boolean depending on that bucket.

### Scoring

```
$ xxd -c 18 -g 1 startest.pyth
0000000: 72 53 6d 21 40 6a 43 22 03 91 5d d3 c3 84 d5 5c df 46  rSm!@jC"..]....\.F
0000012: 69 b5 9d 42 9a 75 fa 74 71 d9 c1 79 1d e7 5d fc 25 24  i..B.u.tq..y..].%$
0000024: 63 f8 bd 1d 53 45 14 d7 d3 31 66 5f e8 22 32 43 64 2e  c...SE...1f_."2Cd.
0000036: 7a 38                                                  z8
$ echo $LANG
en_US
$ pyth/pyth.py startest.pyth < starred.txt
[[345, False], [655, True]]
$ pyth/pyth.py startest.pyth < unstarred.txt
[[703, False], [297, True]]

```
> 15 votes

# Answer
# CJam, 45 bytes, 65.55%

```
l_c"\"#&'(-.19<CEFHIJLMOPSTXY[_qಠ"e=\1b8672>|

```

This checks if the first character is in a specific list or the sum of all code points is larger than 8,672.

### Scoring

```
$ cat startest.cjam
1e3{l_c"\"#&'(-.19<CEFHIJLMOPSTXY[_qಠ"e=\1b8672>|}*
$ java -jar cjam-0.6.5.jar startest.cjam < starred.txt | fold -1 | sort | uniq -c
    308 0
    692 1
$ java -jar cjam-0.6.5.jar startest.cjam < unstarred.txt | fold -1 | sort | uniq -c
    619 0
    381 1

```
> 14 votes

# Answer
# Matlab/Octave, 17 bytes 60.15%

**Correctly classifies 490 messages as stared, 713 messages as unstared**

Current version:

Just checking the length.

```
f=@(w)numel(w)>58

```

Old version:

Could be translated to any other language. It just checks whether the message contains the words *star* or not. `score: 59/911/52.5%`

```
f=@(w)nnz(strfind(lower(w),'star'))>0 %

```

Results for testcases using this code:

```
slCharacterEncoding('UTF-8');

fid = fopen('codegolf_starred_messages_starred.txt');
line = fgetl(fid);
starred = 0;
while ischar(line)
    if f(line);
        starred = starred +1;
    end

    disp(line)
    line = fgetl(fid);
end
fclose(fid);

fid = fopen('codegolf_starred_messages_unstarred.txt');
line = fgetl(fid);
unstarred = 0;
while ischar(line)
    if ~f(line);
        unstarred = unstarred +1;
    end

    disp(line)
    line = fgetl(fid);
end
fclose(fid);

disp(['  correctly classified as *ed: ',num2str(starred)])
disp(['correctly classified as un*ed: ',num2str(unstarred)])
disp(['                  total score: ',num2str((starred+unstarred)/20),'\%'])

```
> 6 votes

# Answer
# JavaScript ES6, 0.615 = 61.5%

342 correctly identified as starred, 888 correctly identified as unstarred, `(342+888)/2000 = 0.615`

```
x=>-~x.search(/(bo|le)x|sta|ಠ|ツ/i)

```

Test like this on this or this:

```
r=document.body.innerHTML.replace(/<\/*pre>/g,"").split`
`.filter(x=>-~x.search`(bo|le)x|sta|ಠ|ツ`).length

```

I STILL MIGHT GET YOU, MY PRETTY!
> 3 votes

# Answer
## CJam, 32 bytes, Overall score of 0.5605 (56%).

Correctly identifies 428 starred messages and 693 unstarred messages. Total score is `(360+730)/2000=0.545`.

```
l_el"sta"/,1>\,)4%!|

```

Not expecting to win, Ill see how it performs. Above is the code for a single message, to run with multiple use this modified version that returns amount of starred messages:

```
1000{l_el"star"/,1>\,)6%!|}fA]:+

```

Just test it with STDIN being the raw text of either file. Returns true if the message contains "star" or if `length + 1 mod 4 = 0`.
> 3 votes

# Answer
# Retina, 46 bytes, 68.55

```
^.*([zj_C;&¡-ﬀ]|sta|san|soc|bo|eo|xk|l.x|<.>)

```

679 star : 692 unstar

Switched to Retina to get some more regexes in... Still not done.
> 3 votes

# Answer
# C# 6.0 (.NET Framework 4.6), 50 Bytes, 63,60%

```
bool s(string i)=>Regex.IsMatch(i,"ol|tar|l.x|ಠ");

```

Program i used for testing purposes:

```
void Main()
{
    var starred = @"C:\starred.txt";
    var unstarred = @"C:\unstarred.txt";

    var linesStarred = File.ReadAllLines(starred);
    var linesUnstarred = File.ReadAllLines(unstarred);

    var cls = linesStarred.Count();
    var clsc = 0;

    foreach (var line in linesStarred)
    {
        if ( s(line) ) clsc++;
    }

    var clu = linesUnstarred.Count();
    var cluc = 0;

    foreach (var line in linesUnstarred)
    {
        if (!s(line)) cluc++;
    }

    $"Starred {clsc}/{cls} correct ({(clsc/cls*100):0.00}%)".Dump();
    $"Unstarred {cluc}/{clu} correct ({(cluc /clu*100):0.00}%)".Dump();
    $"{(((clsc+cluc)/(decimal)(cls+clu))*100):0.00}".Dump();
}

bool s(string i)=>Regex.IsMatch(i,"ol|tar|l.x|ಠ");

```
> 1 votes

---
Tags: classification, test-battery
---


title: Create a CleverBot

text:
# Question
Title: Create a CleverBot
CleverBot is a conversational AI that works fundamentally by repeating responses from real humans it has heard previously. It starts off pretty dumb, but once the database becomes *(a lot)* larger it begins sounding more like an actual person!

## How your program should work

1. **Output `Hi!`**
2. **Receive the user's reply as a string**
    * The reply is added to a list of responses associated with the program's last output (eg. the first reply would associate with `Hi!`).
3. **Output one of the responses associated with the reply from step 2**
    * Every output has a list of responses associated with it.
    * The response should be randomly selected from the list of associated responses.
    * Matching of previous replies is case-insensitive and without symbols (only `0-9`, `A-Z` and space are matched). For example, entering `hi` could return any response associated with `hi`, `Hi!`, `///H|||I\\\`, etc.
    * If the user's reply does not match any previous responses, randomly select a response from the **entire** list of responses.
4. **Repeat steps 2 and 3 indefinitely**

## Rules

* Output must be exactly the same as the user originally entered it
* If a reply that needs to be added to the list of responses is already in the list, it can be optionally be added again (so it appears in the list twice)
* Input will never be empty and will only contain printable ASCII (code points `32` to `126`)
* All possible random values must have an equal chance of occurring
* Must be a full program (not just a function)
* Must output to `STDOUT` or closest equivalent
* Must take input from `STDIN` or closest equivalent

## Test Case

```
Hi!
> hi...
hi...
> HI
HI                               // could output "hi..." or "HI"
> How are you?
How are you?                     // could output "hi...", "HI" or "How are you?"
> Good.
Good.                            // could output "hi...", "HI", "How are you?" or "Good."
> ~!@#$*`'"(how ar%&e you_\|./<?
Good.
> Good.
~!@#$*`'"(how ar%&e you_\|./<?   // could output "~!@#..." or "Good."
> 2Good.
HI                               // could output any of the user's previous replies

```

This is . Shortest answer in bytes wins!

# Answer
# JavaScript (ES6) ~~155~~ 148 bytes

```
c=t=>t.replace(/[^\dA-Z ]/gi,"");r=["Hi!"];for(a=[],m={};u=prompt(alert(o=r[new Date%r.length]));r=m[c(u)]||a)(m[o=c(o)]=m[o]||[]).push(u),a.push(u)

```

## Less golfed:

```
c=t=>t.replace(/[^\dA-Z ]/gi,"");
r=["Hi!"];
for(a=[], m={}; u=prompt( alert( o=r[new Date%r.length] ) );
r= m [ c(u) ] || a )( m[ o=c(o) ] = m[o] || [] ).push(u), a.push(u)

```
* *3 bytes saved thanks to @balint*
> 2 votes

---
Tags: code-golf, string, natural-language
---