One Problem, Five Programming Languages LIVE!

preview_player
Показать описание
We will solve one programming problem in multiple programming languages (C++, APL, J, Clojure, Python & maybe more)
Рекомендации по теме
Комментарии
Автор

This is a really nice problem for building strong-typing muscles. Here's a solution which doesn't quite make it. I think it shows Haskell is not there yet for writing software that will scale up in generality - the right functions are hard to find, missing completely, or cause difficult import conflicts. For example, we should have a chunksOf :: PosInt -> [a] -> [NonEmpty a] or more general and then an uncons variant which doesn't wrap the result in a Maybe. As a result it's easier to use two corecursive functions instead of what's below.

Improvements to make: better names, change 'f' to work even on empty strings using Compose to avoid fromJust.

import Data.List.Split (chunksOf)
import Control.Monad
import Data.Char
import Data.Profunctor
import Data.Maybe
import Control.Lens

-- cts3 'a' "01" = "ab"
-- cts3 'a' "1" = "b"
-- cts3 'a' "" = ""
cts3 c = fmap (chr . (ord c +) . digitToInt)
cts3dimap c = fmap (\n -> dimap ord chr (+ digitToInt n) c)
cts3partialpf = fmap . flip (\n -> dimap ord chr (+ digitToInt n))
cts3pointfree = fmap . flip (dimap ord chr . (+) . digitToInt)


-- f2 "a1" = "ab"
-- f2 "a" = "a"
f2 = uncurry cts3 . fmap ('0':) . fromJust . uncons

-- g "a1b2c3d" = "abbdcfd"
g = onEachCouple f2 where {onEachCouple = dimap (chunksOf 2) join . fmap }

tricky
Автор

Clojure solution:-

(defn replace-digits [s]
(let [shift (fn [[a i]] [a (+ a i -48)])]
(->> s
(map int)
(partition 2)
(mapcat shift)
(map char)
(apply str))))

BigBeesNase
Автор

One more Clojure solution with reduce fn:

(defn shift
"Takes digit char, returns int offset from zero."
[nbr]
(- (int nbr) (int \0)))

(defn next-pair
"Reducing fn, takes acc, the destructured pair [chr nbr]
and returns next acc."
[acc [chr nbr]]
(conj acc chr (if nbr (char (+ (int chr) (shift

(defn replace-digits
"Takes alpha-digit string, returns digit replaced string."
[s]
(apply str (reduce next-pair [] (partition-all 2 s))))

jonseltzer
Автор

Oh my that's some lispy haskell :D
The Enum typeclass has a notion of a successor and predecessor so you can just do:
replaceDigits s = head s : mapAdjacent (\l r -> if isAlpha l then succ l else r) s

mapAdjecent is not in the standard library but it's just defined as zipWith f <*> tail
so we could just write: replaceDigits s = head s : (zipWith (\l r -> if isAlpha l then succ l else r) <*> tail) s

here's a pointfree version, but it really isn't any shorter: replaceDigits = liftA2 (:) head (mapAdjacent (liftA2 if' isAlpha succ))
or why not: replaceDigits = (:) <$> head <*> (zipWith (if' <$> isAlpha <*> succ) <*> tail) ? ;)

ebn__
Автор

Thanks for grinding through that. I learned a lot. Especially the J. It sounds intriguing.

dialecticalmonist
Автор

At least in J you could avoid the “if” by doing non overlapping windows in the scan, i.e. _2<\s

Автор

My solution in clojure

(defn replace-digits [s]
(->> s (partition 2) (mapcat (fn [[c s]] (list c (shift c (Character/getNumericValue (apply str)))

(defn shift [c x]
(char (+ (int c) x)))

Making use of destructuring inside a lambda instead of using an anonymous function, as well as my favorite mapcat which is (apply concat (map f lst))

k-guardian
Автор

Truly interesting & fun. Thanks. !

aly-bocarcisse
Автор

Heres my clojure solution to this problem

(defn replace-digits [input]
(->> input
(reductions (fn [l r]
(if (Character/isLetter r)
r
(char (+ (int l) (Character/digit r
(apply str)))

vilimkrajinovic
Автор

Will there be a recap video in the usual format?

lorenzobolis
Автор

police coming to get you for an illegally good algorithm ;)

EricMesa