Zig
Learn Zig by typing explicit, low-level code.
Type your way into Zig: explicit allocators, comptime metaprogramming, error unions and try, optionals, and slices with no hidden control flow. Each snippet is idiomatic Zig, and an AI tutor explains every line — why passing an allocator makes allocation visible, how comptime runs code at compile time — so Zig's no-surprises philosophy clicks as you type.
Progress0 / 688 solved · 0/50 sections
best wpm
0
avg wpm
0
accuracy
0%
runs
0
level
1
rating
1000
Run Zig on your machine
1. Install the toolchain
brew install zig2. Save your code as hello.zig, then compile & run
zig run hello.zigprogress by section
1Fundamentals0/9start →
2Strings In Depth0/19start →
String literalsClassify ASCII bytesCompare with mem.eqlFind a single byteIterate over byteslen counts bytesMultiline stringsStrings are byte slicesPrefix and suffixFormat with an allocatorUppercase ASCIIFormat into a stack bufferFind a substringSlice by byte offsetSplit on a byteSplit on a sequenceTokenize collapses gapsConcatenate with an allocatorJoin with a separator
3Values & References0/18start →
Address-ofPass by value copiesRead-only pointersDereference with .*Single-item pointersPass by pointerMutate through a pointerOptionals vs pointersMutable slicesSlices are fat pointersPointer to a structSwap through pointersPointer to an arrayOptional pointersReturn a pointerMethods that mutateMany-item pointersSentinel-terminated pointers
4Slices & Arrays0/18Unlock →
5Data structures0/10Unlock →
6Iterators0/20Unlock →
sum / product / countindex with 0..take and skip by slicingwhile with an indexchain two sourcesfilter into a listfold into an accumulatorfor over a slicepartition into two listsreduce without a seedany / all / find / positionsplit iteratorstep and reversetake_while by breaktokenize iteratorcollect into a hash mapparse and keep the good onesscan (running totals)std.mem.windowcustom iterator struct
7Traits0/20Unlock →
Default field valuesAn add methodAn equality methodConversion constructorA negation methodScale by a scalarAdd into the receiverdeinit for cleanupComptime duck typingA struct as a map keyAn indexing methodSort with a comparatorFallible conversionAn associated typeValue copy vs deep copyCustom formattingFold into a summary typeExpose an iteratorA custom iteratorA delegating wrapper
8Generics0/15Unlock →
anytype parameterGeneric functionTwo type parameters@TypeOf and @typeNamecomptime evaluationGeneric default valueGeneric min over a sliceGeneric newtype wrapperGeneric structGeneric sum over anythingGeneric tagged unionType parameterized by a lengthGeneric with a key functionGeneric methodsReflection with @typeInfo
9Lifetimes0/20Unlock →
No lifetime annotationsStatic string dataCapturing by structFunction pointersReturn a borrowed sliceReturn a field pointerAn arena scopeA reference wrapperReturn one of two inputsPointer into a sliceMethod returning a field sliceA struct holding a sliceTwo borrowed fieldsA union that borrowsA comptime-generic printerA generic borrowing structLongest in a slice of stringsA borrowed growable listA borrowing parserAn iterator borrowing input
10Closures0/20Unlock →
A function valueCapture by valueExplicit body and return typeFunction pointersMultiple parametersCallbacksA functor as a predicateA function as a parameterA functor (captured context)Functions drive a loopsort with a comparatorA stateful accumulatorA comptime function parameterCurrying with a functorA mutating functorReturn a functorsort with a contextCompose functionsAn array of function pointersReturn different functions
11Pattern Matching0/20Unlock →
switch on valuesExhaustive enum switchif/else on an error unionMultiple values per prongif on an optionalRange prongsPull struct fieldsswitch as an expressionDestructure a tuplewhile on an optionalCapture the valueA guard via inner ifIgnore parts with _Switch a tagged unionBind or divergeinline elseSwitch on lengthCapture the payload by pointerLabeled switchRecursive union
12Error Handling0/21Unlock →
catch with a defaultdefer cleanup@errorNameCustom error setHandle a parse errorcatch |err|catch and assertError union returnif with error captureerror union in maintry propagatesunreachableanyerrorInferred error setStop at the first errorMerge error setsMultiple error kindsswitch on an errorChaining tryerrdefer cleanupAttach context to errors
13Option & Result0/21Unlock →
An optional valuecatch a defaultif with a captureCompare against nullorelse defaultForce unwrap with .?catch |err| on a ResultSearch returns an optionalMap lookup is optionalOptional struct fieldReturn an optionalChained orelseError union as ResultTransform an optionalNested optionalsOptional pointerorelse with a blockorelse returnDrain with an optionaltry then optionalwhile over an iterator
14Conversions0/15Unlock →
15Collection Conversions0/19Unlock →
Flatten nested slicesMap keys to a sliceMap values to a slicePairs to a mapSet to a sorted sliceSlice to a double-ended listSlice to a setSlice to sorted-uniqueBoxing and unboxingSlice to a frequency mapMap keys to a setIterate a map in key orderMap to a slice of pairsTwo slices to a mapUnique, keeping orderGroup a slice into a mapInvert a mapList to an owned sliceA slice of tagged unions
16Math0/14Unlock →
17Encoding0/22Unlock →
String to bytesASCII checks and caseBytes to StringChar to code pointChar digit valueBinary, octal, hex formattingBig-endian bytesList code pointsEscape a charHex encodeLittle-endian bytesBytes vs charsParse a number in a baseLossy UTF-8 decodeCaesar cipherHex decodePercent-encodeROT13XOR cipherPercent-decodeBase64 decodeBase64 encode
18Random0/20Unlock →
Seed from the clockCoin flipPick a random elementRandom alphanumeric stringWeighted true/falseRandom bytesRandom enum variantRandom seed from OS entropyA linear congruential generatorPassword generatorRandom number in a rangeReproducible sequencesAn xorshift generatorRoll many diceSample k without replacementFisher-Yates shuffleRandom f64 in [0, 1)UUID-v4-shaped stringWeighted choiceNormal distribution
19Data I/O0/18Unlock →
Parse CSV into rowsTab-separated valuesBuild a CSV stringSelect one columnCSV into a number matrixSplit off the headerWhitespace-separated matrixRead a data fileSerialize records to CSVSkip blanks and commentsPrint an aligned tableSerialize CSV to write outWrite a matrix as textAppend a rowParse key=value configRound-trip write then readStream lines one at a timeDrop unparseable rows
20Linear Algebra0/21Unlock →
Matrix shapeScalar multiplyA matrix of zerosElementwise addArgmax of a vectorIdentity matrixOne-hot encodeTraceStack rows (vstack)ReLU and sigmoidApply a function elementwiseColumn meansColumn sumsCosine similarityFlat storage, 2D indexingMatrix times vectorTransposeMatrix multiplyMin-max normalize columnsSoftmaxStandardize columns (z-score)
21Text Processing0/16Unlock →
22Date & Time0/12Unlock →
23Memory0/12Unlock →
24Modules0/20Unlock →
Bring a name into scope@importStruct as a namespaceConstants in a namespaceAn enum in a namespaceAlias several itemsNested namespacesPublic vs privateFully-qualified pathRename with an aliasReach a file-scope declarationA type in a namespaceThe current namespaceA type and a functionA utility namespaceEncapsulation with a getterFlatten a deep pathRe-export a declarationReach a sibling namespaceAn interface
25Macros0/20Unlock →
The ** operatorstd.debug.assertA comptime parametercomptime instead of macrosswitch as matches!@typeName and @tagName@compileLog notecomptimePrintFormat specifiersBuild a list from a literalbufPrint into a bufferBranch at compile timeinline for over a tupleRepeat a blockBuild a map@compileErrorVariadic maxCount tuple fields@hasField and @fieldGenerate code with a type
26Testing0/20Unlock →
expect a booleanA unit testAssert values differMultiple testsTesting string outputTesting a truth tableTesting a bounds checkDoc comments + a testexpectErrorA test helperTesting an optionalTesting an error caseSkip a testTesting a methodComparing floatsA specific errorTest private functionsTests use tryTable-driven testsThe testing allocator
27Algorithms0/10Unlock →
28Sorting Algorithms0/12Unlock →
29Expression Parsing0/6Unlock →
30Idioms0/10Unlock →
31OOP & Traits0/8Unlock →
32Trait Objects0/14Unlock →
Default method on an interfaceAn array of mixed variantsReturn one of several typesDispatch through an interfaceOne fixed type vs manyStore function pointersA slice of interfacesStatic vs dynamic dispatchComposed interfacesAn interface over borrowed dataRecover the concrete typeA handler registryShared implementer on the heapA uniform vtable table
33Design Patterns0/14Unlock →
35File I/O0/6Unlock →
36Filesystem0/18Unlock →
Does a path exist?Copy a fileCreate nested directoriesFiles vs directoriesBuild a pathList a directoryRename or moveFile metadataPath componentsRemove files and treesWrite to a temp directoryChange the extensionFilter by extensionLast modified timeAbsolute pathSorted listingTotal size of a treeWalk the tree
37Networking0/16Unlock →
38Concurrency0/7Unlock →
39Unsafe & FFI0/14Unlock →
40Commands0/14Unlock →
41Array0/10Unlock →
43String0/10Unlock →
45Interval0/5Unlock →
46Linked List0/6Unlock →
47Tree0/14Unlock →
Maximum Depth of Binary TreeInvert Binary TreeSame TreeLowest Common Ancestor of a BSTBinary Tree Level Order TraversalSubtree of Another TreeImplement Trie (Prefix Tree)Kth Smallest Element in a BSTValidate Binary Search TreeAdd and Search WordConstruct Binary Tree from Preorder and InorderBinary Tree Maximum Path SumSerialize and Deserialize Binary TreeWord Search II