Challenge

You have one string of input bytes, output the last byte in it.

Rules

Your submission may be a program or function outputting the last byte in the input which

• is either a string, stdin or command-line arguments, and
• is non-empty.

I was trying to solve this with brainfuck, however all languages are allowed to participate. This is .

Examples

"?" -> "?"
"29845812674" -> "4"

• Welcome, I changed your question to fit our format more properly (note this is what the sandbox is for, usually). However in its current state the challenge is very easy (also in bf), so not sure about that. – ბიმო Mar 17 at 19:11
• I vote against closing; it may be trivial, but that doesn't make it offtopic – MilkyWay90 Mar 17 at 22:30
• @MillyWay I think most of the close votes were before the extensive edit by ბიმო – Sanchises Mar 18 at 6:47
• @ბიმო We have a consensus not to edit off-topic questions to make them on-topic which I think would have applied here. – Laikoni Mar 18 at 7:19
• What kind of string? Is it guaranteed to be ASCII only? Or should we handle UTF-8 (and how?) for example? – FireCubez Mar 18 at 18:28

Retina, 10 9 bytes

(.|¶)*
$1  Try it online! INTERCAL, 270 bytes DO,1<-#1PLEASECOMEFROM(2)DOWRITEIN,1DO.1<-,1SUB#1DO.5<-#1$!1~#256'DO.2<-.3DO(1)NEXTPLEASE.2<-'"!3~#1'$!3~#16'"$"!3~#4'$!3~#64'"'$'"!3~#2'$!3~#32'"$"!3~#8'$!3~#128'"'DO(1010)NEXTPLEASE,1SUB#1<-.3PLEASEREADOUT,1DOGIVEUP(1)DO(1002)NEXTDO(1009)NEXTDO.3<-.3~#255(2)DOFORGET#1  Try it online! Writing this was... interesting. I was thinking I might want to use INTERCAL to INTERCALate, but I'm a bit less sure now. Ungolfed and commented:  DO ,1<-#1 PLEASE NOTE We want the input array to only have space for one element, so it will only take one at a time DO COME FROM (2) DO WRITE IN ,1 PLEASE NOTE If this is the first byte of the input, it'll write its value... but if not, it'll write the previous value minus its value mod 256. DO .1<-,1SUB#1 DO .5<-#1$!1~#256'    PLEASE NOTE .5 is 3 if the input is 256, 2 otherwise
DO .2<-.3
DO (1) NEXT

PLEASE NOTE If we're here, we've found the end of the input. Now, we need to print it back out... C-INTERCAL's
array I/O, in order to determine what it will actually print, subtracts the value it's going to print from the
previous one (still mod 256, and with the previous value defaulting to 0), and then reads the bits of the byte
backwards. So in order to go from the value we want to display to the value we need to feed into READ OUT, we
reverse the bits and then subtract from 256. The nightmarish expression on the following line reverses the
bits the best way I could think to: individually select each one out and then mingle them all back
together. It may be possible to emulate the method used in cesspool.c, by using mingle and unary AND as a
substitute for binary AND where we can't afford for select to rearrange it, but it might end up longer...

DO .2 <- '"'.3~#1'$'.3~#16'"$"'.3~#4'$'.3~#64'"'$'"'.3~#2'$'.3~#32'"$"'.3~#8'$'.3~#128'"' DO (1010) NEXT PLEASE NOTE .1 already has 256 in it, which is very convenient for when you need to subtract .2 from 256. DO ,1SUB#1 <- .3 PLEASE NOTE If we just read .3 out, we'd get a Roman numeral instead of the correct output. DO READ OUT ,1 DO GIVE UP PLEASE NOTE End of program. (1) DO (1002) NEXT PLEASE NOTE that that line in syslib does 1001 next, which pops .5 entries off the next-stack and returns control flow to the last one, such that if .5 is 2 flow will come back here, but if it's 3 then it'll go back to the line that nexted to this one. Here we add .1 and .2 into .3, then truncate it to a byte before looping back (while managing the next-stack responsibly so the program doesn't disappear into the black lagoon for any input over 79 (?) bytes) DO (1009) NEXT DO .3<-.3~#255 (2) DO FORGET #1  C (gcc), 31 bytes f(int*s){gets(s),printf("%s");}  Try it online! • O_o how does this even work – ASCII-only Mar 31 at 10:52 • I have no idea, it just works. – Natural Number Guy Mar 31 at 14:07 • Impressive list of complaints from the compiler! – roblogic Sep 27 at 5:00 Scratch 3.0, 7 blocks/68 bytes or, as scratchblocks syntax when gf clicked ask()and wait say(letter(length of(answer))of(answer  Did I mention this was done 100% on mobile? Because it was really hard making this, but I think it was worth it. Wolfram Language (Mathematica), 16 bytes #~StringTake~-1&  Try it online! C# (.NET Core), 81 bytes, command-line input class M{static void Main(string[] a){System.Console.Write(a[0][a[0].Length-1]);}}  Try it online! If you run this from an actual command line, you will need to wrap your string in quotes if it contains spaces. C# (.NET Core), 115 bytes, console input using C=System.Console;class M{static void Main(string[] a){int c=0,d;while((d=C.Read())>-1)c=d;C.Write((char)c);}}  Try it online! This feels kinda janky, but it does work. Interestingly, I can't save any bytes with a for loop as the code stands. Perl 6, 11 bytes *.comb[*-1]  Try it online! Anonymous Whatever lambda that takes a string, splits it into characters, and returns the last one. Batch, 24 bytes @set s=%1 @echo %s:~-1%  Takes input as a command-line argument. Note that arguments can't include special characters or spaces, but you can fake arguments with spaces in this case by preceding it with a ", which results in a single argument that begins with ", however there is no easy solution for arguments that include special characters. Batch can't easily read "all of stdin". To read up to but not including the first newline itself would however be a byte shorter: @set/ps= @echo %s:~-1%  Edit: A version that handles arbitrary characters in a (quoted) argument for 92 bytes: @set s="%~1" @set "s=%s:~-2,1% @if "%s%"=="" (echo ^")else for %%s in ("%s%")do @echo %%~s  Explanation: The first line makes a copy of the argument in a variable and ensures that it is quoted. The second argument then takes the second last character (because the quote is now the last character). However, if that was also a quote then this results in an empty variable, so we need to special-case that and output a (quoted) quote. Otherwise, we still need to quote the character in case it is a special character as echoing "%s%" will echo the quotes and echoing %s% will actually interpret special characters, so the variable needs to be quoted to allow it to be parsed but then immediately unquoted so it can be printed. This is achieved using the for command. 86 bytes to read up to but not including the first newline from stdin while supporting special characters: @set/ps= @set "s=%s:~-1% @if "%s%"=="" (echo ^")else for %%s in ("%s%")do @echo %%~s  Scratch 3.0, scratchblocks3 syntax As a function, 61 bytes define l ask[]and wait say(letter(length of(answer))of(answer  As a full program, 68 bytes when gf clicked ask[]and wait say(letter(length of(answer))of(answer  Try both online Befunge-98, 5 bytes ~2j@,  Try it online! Explanation: ~ Take input 2j Skip next two instructions ~ Repeat until EOF, where it reflects @, Print the last character and exit  C# (Visual C# Interactive Compiler), 11 bytes x=>x.Last()  Try it online! • you can use a function :P – ASCII-only Mar 18 at 0:47 • OK - Ill update my answer :) – dana Mar 18 at 1:21 • uhm why is testcase in STDIN not footer – ASCII-only Mar 18 at 1:38 • Wow - It's been a while. Thanks for pointing that out ;) – dana Mar 18 at 1:39 • That's not how I understand it. I understand that it should print the last non-empty character. We need to ask OP. – Ven Mar 18 at 17:33 Japt, 1 byte Ì  Try it online! -1 byte thanks to Quintec! • 1 byte – Quintec Mar 18 at 2:00 APL+WIN, 4 bytes ¯1↑⎕  Prompt for input string and select last byte. Whitespace, 54 bytes [N S S N _Create_Label_LOOP][S S S N _Push_0][S N S _Duplicate_0][T N T S _Read_STDIN_as_character][T T T _Retrieve_input][S N S _Duplicate][S S S T S T S N _Push_10][T S S T _Subtract][N T S S N _If_0_Jump_to_Label_PRINT][N S N N _Jump_to_Label_LOOP][N S S S N _Create_Label_PRINT][S N N _Discard_top][T N S S _Print_as_character]  Letters S (space), T (tab), and N (new-line) added as highlighting only. [..._some_action] added as explanation only. Since Whitespace can only take input as integer or character, we must add a trailing character to indicate we're done with the input-string after reading it character by character, for which I've used a newline. Try it online (with raw spaces, tabs and new-lines only). Example run: input = A2# Command Explanation Stack Heap STDIN STDOUT STDERR NSSN Create Label_LOOP [] SSSN Push 0 [0] SNS Duplicate top (0) [0,0] TNTS Read STDIN as character [0] {0:65} A TTT Retrieve at heap address (0) [65] {0:65} SNS Duplicate top (65) [65,65] {0:65} SSSTSTSN Push 10 [65,65,10] {0:65} TSST Subtract top two (65-10) [65,55] {0:65} NTSSN If 0: Jump to Label_PRINT [65] {0:65} NSNN Jump to Label_LOOP [65] {0:65} SSSN Push 0 [65,0] SNS Duplicate top (0) [65,0,0] TNTS Read STDIN as character [65,0] {0:50} 2 TTT Retrieve at heap address (0) [65,50] {0:50} SNS Duplicate top (50) [65,50,50] {0:50} SSSTSTSN Push 10 [65,50,50,10] {0:50} TSST Subtract top two (50-10) [65,50,40] {0:50} NTSSN If 0: Jump to Label_PRINT [65,50] {0:50} NSNN Jump to Label_LOOP [65,50] {0:50} SSSN Push 0 [65,50,0] SNS Duplicate top (0) [65,50,0,0] TNTS Read STDIN as character [65,50,0] {0:35} # TTT Retrieve at heap address (0) [65,50,35] {0:35} SNS Duplicate top (35) [65,50,35,35] {0:35} SSSTSTSN Push 10 [65,50,35,35,10] {0:35} TSST Subtract top two (35-10) [65,50,35,25] {0:35} NTSSN If 0: Jump to Label_PRINT [65,50,35] {0:35} NSNN Jump to Label_LOOP [65,50,35] {0:35} SSSN Push 0 [65,50,35,0] SNS Duplicate top (0) [65,50,35,0,0] TNTS Read STDIN as character [65,50,35,0] {0:10} \n TTT Retrieve at heap address (0) [65,50,35,10] {0:10} SNS Duplicate top (10) [65,50,35,10,10] {0:10} SSSTSTSN Push 10 [65,50,35,10,10,10] {0:10} TSST Subtract top two (10-10) [65,50,35,10,0] {0:10} NTSSN If 0: Jump to Label_PRINT [65,50,35,10] {0:10} NSSSN Create Label_PRINT [65,50,35,10] {0:10} SNN Discard top [65,50,35] {0:10} TNSS Print as character to STDOUT [65,50] {0:10} # {0:10} error  Stops with the error: Exit not defined. Japt -h, 1 byte U  Run it online Runic Enchantments, 5 bytes i1Z%@  Try it online! Note that input handling in Runic has implicit conversion and breaks on spaces. \ denotes a literal space (works on newlines too) and numerical values are never strings. Binary-Encoded Golfical, 17 bytes Hex-dump of binary encoded file: 00 60 02 1b 1a 08 01 14 16 14 24 1d 0a 01 14 18 14  Original image: Magnified 45x with colors labeled: The original image (the tiny one, not the magnified version) can be run using the interpreter normally. The binary encoded file (of which a hexdump is included above) can either be transpiled back to the image version with the Encoder program included in the github repo, or run directly using the interpreter by adding the -x flag. Chip-z, 41 bytes S >vvvvvv~t ABCDEFG |Zz||Zz zbcZzfg a de  Try it online! Assumes that either the byte string does not contain zero (\0), or that it designates the end of the string. Alternate solution (45 bytes): azABZbczCDZdezEFZfgzG S-^^----^^----^^----^~t  Try it online! Forth (gforth), 17 bytes : f 1- + 1 type ;  Try it online! Explanation Adds string-length - 1 to the string address and then prints a string of length 1 starting at that address. Code Explanation : f \ start a new word definition 1- \ subtract 1 from string length + \ add result to string address 1 type \ print string of length 1 starting at the new address ; \ end word definition  R, 35 bytes Takes the input, splits it in to a list, outputs the last element of the list. tail(strsplit(scan(,''),'')[[1]],1)  Try it online! Japt -h, 1 byte Can handle input as a string, integer or character/digit array. s  Try it LiveScript, 8 bytes (.[*-1])  Explanation: (.[*-1]) (.[*-1]) # "BIOP": operator section à la Haskell .[ ] # Index into the implicit argument *-1 # In [], "*" refers to the length  F#, 14 8 bytes Seq.last  -6 bytes thanks to aloisdg. Strings are treated as sequences in F#, so you can use the Seq.last function to get the last character in it. • Seq.last is a function. You can remove the let s= – aloisdg says Reinstate Monica Mar 19 at 8:19 Haskell, 4 bytes last  Functions are allowed, right? Also with IO (18 bytes): main=interact$last

• The same answer was already posted, though we do allow duplicate answers as far as I know. – Laikoni Mar 24 at 21:22

C, 3635 34 bytes

x(char*v){printf(v+strlen(v)-1);}


Really simple stuff here. Nothing to ungolf either.

Saved one byte thanks to ceilingcat
Fixed the answer and saved another byte thanks to ASCII-only

• invalid, you need to change to printf – ASCII-only Mar 31 at 10:55

Keg, 1 byte

This is the exact thing that Keg was built for.

,


Explanation

# Push implicit string input
,# Output the last pushed character
# There is no implicit output since something was outputted


TIO

MarioLANG, 18 bytes

>,
"+
)[
!<(-
#==.


Try it online!

code:

>    go right
+    increment it (because EOF = -1)
[    ignore the next command, if current cell = 0
<    go to the left
!    stop moving (Mario is now standing on the elevator (#),
which rides up to the elevator end (")
)    go to the next memory cell
Mario is now at the starting position (>) and runs another round
until the end of input

else (if he ignored the "<" instruction)
(    go one memory cell back (to the last inputted byte)
-    decrement it, so it becomes the original value again
.    print it


Caboose, 1514 bytes

Caboose hates me, because it does. There isn't any convenient string-indexing instruction in Caboose!

var a=input();print(a.endsWith(' ')and' 'or a.endsWith('!')and'!'or a.endsWith('"')and'"'or a.endsWith('#')and'#'or a.endsWith('$')and'$'or a.endsWith('%')and'%'or a.endsWith('&')and'&'or a.endsWith("'")and"'"or a.endsWith('(')and'('or a.endsWith(')')and')'or a.endsWith('*')and'*'or a.endsWith('+')and'+'or a.endsWith(',')and','or a.endsWith('-')and'-'or a.endsWith('.')and'.'or a.endsWith('/')and'/'or a.endsWith('0')and'0'or a.endsWith('1')and'1'or a.endsWith('2')and'2'or a.endsWith('3')and'3'or a.endsWith('4')and'4'or a.endsWith('5')and'5'or a.endsWith('6')and'6'or a.endsWith('7')and'7'or a.endsWith('8')and'8'or a.endsWith('9')and'9'or a.endsWith(':')and':'or a.endsWith(';')and';'or a.endsWith('<')and'<'or a.endsWith('=')and'='or a.endsWith('>')and'>'or a.endsWith('?')and'?'or a.endsWith('@')and'@'or a.endsWith('A')and'A'or a.endsWith('B')and'B'or a.endsWith('C')and'C'or a.endsWith('D')and'D'or a.endsWith('E')and'E'or a.endsWith('F')and'F'or a.endsWith('G')and'G'or a.endsWith('H')and'H'or a.endsWith('I')and'I'or a.endsWith('J')and'J'or a.endsWith('K')and'K'or a.endsWith('L')and'L'or a.endsWith('M')and'M'or a.endsWith('N')and'N'or a.endsWith('O')and'O'or a.endsWith('P')and'P'or a.endsWith('Q')and'Q'or a.endsWith('R')and'R'or a.endsWith('S')and'S'or a.endsWith('T')and'T'or a.endsWith('U')and'U'or a.endsWith('V')and'V'or a.endsWith('W')and'W'or a.endsWith('X')and'X'or a.endsWith('Y')and'Y'or a.endsWith('Z')and'Z'or a.endsWith('[')and'['or a.endsWith('\\')and'\\'or a.endsWith(']')and']'or'~');


If I add more constants, then Caboose will say that there are too many constants in the chunk. Fortunately it passes all test cases given. Basically it (tries to) check the last character against all characters in printable ASCII.

TIO

Python 3, 16 bytes

This is a pretty basic answer, but I think that it is the lowest Python 3 can go...

x=lambda a:a[-1]


TIO

• you don't need the x= here – ASCII-only Mar 31 at 10:57