Code:
LOCAL CRID:="ListExtras API V0.01 © 2018";
LOCAL MORETEXT:="ListExtras by StephenG1CMZ on HP Prime\nInspired by DavidM's Listext on HP48-50.";
LOCAL MN:="ListExtras.";//Name
//IMPORT({List}); //Required
//IMPORT({Means,SortL}); //Required
LOCAL TP;
LOCAL ExBool:=0;//Request Exact//MEX
LOCAL NOVALERR:=ListIsEmptyError;//LPOP
LOCAL BADDIMERR:=ListIsEmptyError;
//Forward
LNMRL(LST);
EXPORT ABOUT()
BEGIN
MSGBOX(CRID);
MSGBOX(MORETEXT);
MSGBOX("An early teaser...\nTotally untested");
END;
TBD()
BEGIN
MSGBOX(MN+"TBD");
END;
EXPORT ArrangeFunctions()
BEGIN
END;
EXPORT LRLLD(LST)
//INVERSE ROTATE (=−1 ROT)
BEGIN
LOCAL HD:=LST(1);
RETURN CONCAT(ListAFTER(LST,1),HD);
END;
EXPORT LROLL(LST)
//ROTATE (=1 ROT)
BEGIN
LOCAL LAST:=LST(0);
RETURN CONCAT(LAST,ListBEFORE(LST,SIZE(LST)));
END;
EXPORT LROT(LST,ROTNUM)
//ROTATE A LIST NUM POSITIONS (NUM SIGNED)
//NEED -1 REPEATEDLY TBD
BEGIN
LOCAL II;
IF ROTNUM THEN
TBD();
FOR II FROM 1 TO ABS(ROTNUM) DO
IF ROTNUM>0 THEN
RETURN LROLL(LST);
ELSE
RETURN LRLLD(LST);
END;
END;
END;
RETURN LST; //NO ROT
END;
EXPORT LSWAP(LST,POSN1,POSN2)
//SWAP 2 ELEMENTS
BEGIN
LOCAL TMP:=LST(POSN1);
LST(POSN1):=LST(POSN2);
LST(POSN2):=TMP;
END;
EXPORT LSSR(LST,POSN1,POSN2)
//REVERSES PART OF A LIST, RETURNS WHOLE LST
//EXT: POSN>0 INCLUDED (NULL=POSN=0)
BEGIN
LOCAL TMP:=REVERSE(ListSLICE(LST,POSN1,POSN2));
LOCAL BEF:=ListBEFORE(LST,POSN1);
LOCAL AFT:=ListAFTER(LST,POSN2);
ListANS:=CONCAT(BEF,CONCAT(TMP,AFT));
RETURN ListANS;
END;
EXPORT LSHUF(LSTNUM)
//SHUFFLES LST
BEGIN
RETURN ListSHUFFLE(LSTNUM);
END;
EXPORT REV(LstStN)
//EXT: REVERSE LISTS STRINGS N
//THIS IMPLEMENT ALSO DOES SUBLISTS
//QUERY DO WE NEED? DOES BUILTIN REVERSE SAME?
BEGIN
TP:=TYPE(LstStN);
CASE
IF TP==TYPELST THEN RETURN REVERSE(LstStN); END;
IF TP==TYPESTR THEN TBD(); END;
DEFAULT
END;
END;
EXPORT EditFunctions()
BEGIN
END;
EXPORT LDDUP(LST)
//EDIT:REMOVE DUPLICATES
//EXT:SAME SEQ
//X:NATIVE SEEMS TO
BEGIN
RETURN ListREMOVEDUPLICATES(LST);
END;
EXPORT LHDTL(LST)
//EDIT: AKA LPOP. NULL=NOVAL ERR
//X: Tail in ListANS. NULL=ListIsEmptyError
BEGIN
RETURN ListHEAD(LST);
END;
EXPORT LINSR(LST,POSN,ITEMS)
//EDIT: INSERT ITEM(S) AKA LINSRT
//INSERTS 1 ITEM OR A LIST OF ITEMS
//QUERY: HOW TO INSERT 1 ITEM OF TYPE LST?
//EXT: POSN<2 NEEDS HANDLING
//X: EXT COMPATABILITY TBD
BEGIN
RETURN ListINSERT(LST,POSN,ITEMS);
END;
EXPORT LINSRT(LST,POSN,ITEMS)
//AKA LINSR
BEGIN
RETURN LINSR(LST,POSN,ITEMS);
END;
EXPORT LFIRST(LST,NUM)
//EDIT: RETURN FIRST ITEMS AKA LFRST
//GUARDS AND NEGATIVES TBD
//EXT: N<0 UNK ERR N==0 NULL
//X:NO ERROR YET
BEGIN
RETURN ListBEFORE(LST,NUM+1);
END;
EXPORT LFRST(LST,NUM)
//AKA LFIRST
BEGIN
RETURN LFIRST(LST,NUM);
END;
EXPORT LLAST(LST,NUM)
//EDIT: RETURN LAST ITEMS
//EXT: N<0 UNK ERR 0 NULL N>LST LST
//X: GUARDS AND NEGATIVES TBD
BEGIN
LOCAL POSN:=SIZE(LST)-NUM;
RETURN ListAFTER(LST,POSN);
END;
EXPORT LPICK(LST,GETLST)
//EXT:EMPTY GET=NULL
BEGIN
RETURN ListGETLIST(LST,GETLST);
END;
EXPORT LPOP(LST)
//EDIT: AKA LHDTL
BEGIN
RETURN LHDTL(LST);
END;
EXPORT LPOPR(LST)
//EDIT: POP LAST ITEM
//EXT: NULL=NULL AND NOVAL ERR
//X: ERR TBD
BEGIN
IF SIZE(LST) THEN
ListANS:=ListBEFORE(LST,SIZE(LST));
RETURN LST(0);
END;
ListANS:={};
RETURN {};
END;
EXPORT LPSHR(LST,ITEM)
//EDIT: PUSH ITEM TO RIGHT OF LST
//EXT: ITEMTYPE=LST:PUSH 1 ITEM NULLNULL={{}}
//X: TBD NULL GUARDS CF LPUSH
BEGIN
LST(0):=ITEM;
END;
EXPORT LPUSH(LST,ITEM)
//EDIT:ADD ITEM TO FRONT
//EXT NULLNULL={{}}
//TBD:NULL GUARDS DONT WORK
//LATER:USE GUARDS IN LIST
BEGIN
IF LST=={} THEN
RETURN {ITEM};
END;
IF ITEM=={} THEN
RETURN CONCAT({},LST);
END;
RETURN ListINSERT(LST,1,ITEM);
END;
EXPORT LRCL(LST)
//EXT:({A}) -> 5 IF A IS 5
//X: ({"2+3"}) -> 5 ==> NOT THE SAME
BEGIN
LOCAL II;
ListANS:={};
FOR II FROM 1 TO SIZE(LST) DO
ListANS(0):=EXPR(LST(II));
END;
RETURN ListANS;
END;
EXPORT LREPL(LST,TARGETLST,REPLLST)
//WHEN TARGETLSTn EXISTS IN LST
//REPLACE IT WITH REPLLSTn
//RETURN MODIFIED LST
//Hint: CALL ListREPLACE FOR EACH n
//QUERY: WHAT HAPPENS IF CHANGED TWICE
BEGIN
LOCAL II;
ListANS:=LST;
//Can this be more efIcient?
FOR II FROM 1 TO SIZE(TARGETLST) DO
ListANS:=ListREPLACE(ListANS,TARGETLST(II),REPLLST(II));
END;
RETURN ListANS;
END;
EXPORT LRMOV(LST,POSNS)
//EDIT: REMOVE ITEMS
//EXT: REMOVE MULTIPLE POSNS IGNORING DUPLICATE POSNS
//X: SINGLE POSN ONLY FOR NOW
BEGIN
IF TYPE(POSNS)==TYPELST THEN
TBD();
END;
RETURN ListREMOVEX(LST,POSNS);
END;
EXPORT GroupFunctions()
BEGIN
END;
EXPORT GrpLCLLT(LSTS)
//List Collate. INVERSE OF LDIST
BEGIN
LOCAL II,JJ;
LOCAL SIZE1:=SIZE(LSTS(1));
ListANS:={};
//REQUIRE ALL SIZES SAME
FOR II FROM 1 TO SIZE(LSTS) DO
IF SIZE1≠SIZE(LSTS(II)) THEN
RETURN "BAD DIM";//UNK ERR
END;
END;
//OK, COLLATE
FOR JJ FROM 1 TO SIZE1 DO
FOR II:=1 TO SIZE(LSTS) DO
ListANS(0):=LSTS(II,JJ);
END;
END;
END;
EXPORT LDIST(LST,NUM)
//DISTRIBUTE ITEMS INTO NUM SUBLISTS.INVERSE OF LCLLT. CF LSDIV
//EXT: NUM MUST EVENLY DIVIDE LISTSIZE. UNK ERR
//HINT REPEATEDLY CALL ListBEFORE
BEGIN
TBD();
END;
EXPORT LGRP(LST)
//GROUP REPEATED ELEMENTS IE NO DUPLICATS
BEGIN
RETURN ListREMOVEDUPLICATES(LST);
END;
EXPORT LRPCT(LST)
//LIST LGRP ELEMENTS AND COUNTS
//EXT: NULL={{},{}}
//X:DITTO
BEGIN
RETURN ListCOUNTS(LST);
END;
EXPORT LRPCTo(LSTVLSTF)
//INVERSE
BEGIN
LOCAL LSTV:=LSTVLSTF(1);
LOCAL LSTF:=LSTVLSTF(2);
RETURN ListUNCOUNTS(LSTV,LSTF);
END;
EXPORT LSDIV(LST,SUBSIZE)
//SPLIT A LIST INTO LISTS OF SIZE SUBSIZE. CF LDIST
//EXT: NO REMNANT. UNK ERR.
//HINT REPEATEDLY CALL ListBEFORE
BEGIN
TBD();
END;
EXPORT LXIL(LST)
//FLATTEN TOP LISTS
BEGIN
RETURN ListFLATTENTOP(LST);
END;
EXPORT LXILR(LST)
//FLATTEN LISTS RECURSIVELY
BEGIN
RETURN ListFLATTENALL(LST);
END;
EXPORT RSPLT(LstStN,RSIZE)
//RIGHT SPLIT Lst St Or N. SZ=IP(RSIZE)
//EXT:LST: RETURN 2 LISTS, RIGHT OF SIZE RSIZE
//SIMILARLY FOR ST AND N
BEGIN
TBD();
END;
EXPORT SPLIT(LstStN,LSIZE)
//SPLIT A Lst St OR N. (IE LSPLT CF RSPLT) SZ=IP(LSIZE)
BEGIN
TBD();
END;
EXPORT SLISTTo(LST)
//EXT:SAFE LST AVOIDING GARBAGE COLLECTION
//X: IRRELEVANT?
BEGIN
RETURN LST;
END;
EXPORT MakeFunctions()
BEGIN
END;
EXPORT MakeLASEQ(FRM,CHNG,NUM)
BEGIN
LOCAL XX;
RETURN IFTE(NUM>0,MAKELIST(FRM+(CHNG*XX),XX,0,NUM-1),{});
END;
EXPORT MakeLDSEQ(FRM,CHNG,NUM)
BEGIN
LOCAL XX;
IF CHNG==0 THEN
RETURN "NaN";//DIVBY0
END;
IF (TYPE(FRM)==TYPE(CHNG) AND TYPE(CHNG)==TYPEINT) OR ExBool THEN
RETURN IFTE(NUM>0,MAKELIST(exact(FRM/(CHNG^XX)),XX,0,NUM-1),{});
END;
RETURN IFTE(NUM>0,MAKELIST(FRM/(CHNG^XX),XX,0,NUM-1),{});
END;
EXPORT MakeLMSEQ(FRM,CHNG,NUM)
BEGIN
LOCAL XX;
RETURN IFTE(NUM>0,MAKELIST(FRM*(CHNG^XX),XX,0,NUM-1),{});
END;
EXPORT MakeLSEQ(CNT)
//Create CNT REAL integers
//Return Real integer (No N)
BEGIN
LOCAL XX;
RETURN ListANS:=IFTE(CNT,MAKELIST(XX,XX,SIGN(CNT),CNT),{});
END;
EXPORT MakeLSEQR(FRM,TOO)
//Create CNT REAL integers
//Return Real integer (No N)
BEGIN
LOCAL XX;
RETURN ListANS:=IFTE(TOO-FRM,MAKELIST(XX,XX,FRM,TOO),{});
END;
EXPORT MakeLMRPT(ITEMS,RPTCNT)
BEGIN
IF RPTCNT<0 THEN
RETURN {};//OR NEGATE
END;
IF TYPE(ITEMS)≠TYPELST AND RPTCNT==1 THEN
//GUARD AGAINST SINGLE ITEM ONCE NOT RETURNING A LIST
RETURN MakeLMRPT({ITEMS},RPTCNT);
END;
IF RPTCNT>1 THEN
RETURN CONCAT(ITEMS,MakeLMRPT(ITEMS,RPTCNT-1));
END;
RETURN IFTE(RPTCNT,ITEMS,{});
END;
EXPORT MathFunctions()
BEGIN
END;
EXPORT LMAX(LST)
//EXT: CAN ALSO MAX LISTS OF STRINGS
//EXT: NULL=INVALID DIM
//X: NUMERICS ONLY
BEGIN
//RETURN ListMAX(LST);
RETURN MAX(LST);
END;
EXPORT LMIN(LST)
//EXT: CAN ALSO MIN LISTS OF STRINGS
//EXT: NULL=INVALID DIM
//X: NUMERICS ONLY
BEGIN
//ListMIN NOT IMP?
RETURN MIN(LST);
END;
EXPORT LSUM(LST)
//HANDLES NULL
BEGIN
//RETURN ListΣLIST(LST);
END;
EXPORT LPROD(LST)
//HANDLES NULL
BEGIN
//RETURN ListΠLIST(LST);
END;
EXPORT SortFunctions()
BEGIN
END;
EXPORT KSORT(LST,KEYLST)
//EXT:NULL KEY RETURNS TARGET UNCHANGED
//EXT:NULL TARGET AND NON NULL KEY=BAD DIM
//RETURN 2 LISTS
BEGIN
RETURN SortByKeyLST(LST,KEYLST);
END;
EXPORT KSORTFUN(LST,KEYLST,KEYFUNC)
//Pysort implements sort functions
//NB The ext list sequence is not implemented
BEGIN
MSGBOX("Use SORTL.Pysort");
END;
EXPORT StringFunctions()
BEGIN
END;
EXPORT StringLOCASE(ST)
//EXT:ST
//X-ALSO LST
BEGIN
RETURN LOWER(ST);
END;
EXPORT StringUPCASE(ST)
//EXT:ST
//X-ALSO LST
BEGIN
RETURN UPPER(ST);
END;
EXPORT RPTCHR(ST,RPTCOUNT)
//QUERY: IN EXT IF STRING IS >1 CHAR
//IS THE COUNT THE NUMBER OF REPETITIONS OF STRING
//OR NUMBER OF CHARACTERS
//(REPETITIONS EASIER?)
//HINT I HAVE IMPLEMENTED THIS RECURSIVELY IN A PROGRAM
BEGIN
TBD();//BUT WHERE
END;
EXPORT TestFunctions()
BEGIN
END;
EXPORT LCNT(LST,ITEM)
//NB TO COUNT ITEM=LISTS SEE IMPLEMENT
BEGIN
RETURN ListCOUNTITEMS(LST,ITEM);
END;
EXPORT LEQ(LST)
//TST ALL ITEMS IN 1 LST ARE SAME
//EXT: NULL OR SIZE 1 RETURNS TRUE (NO NON-MATCHES)
BEGIN
LOCAL XX;
LOCAL TMP:=LST(1);
ListANS:=MAKELIST(TMP,XX,1,SIZE(LST));
RETURN EQ(LST,TMP);
END;
EXPORT MPOS(LstSt,ITEM)
//Find ITEM in Lst or St
BEGIN
IF TYPE(LstSt)==TYPELST THEN
RETURN ListFIND(LstSt,ITEM);
ELSE
TBD();
END;
END;
EXPORT MPOSL()
//AS MPOS BUT IF LSTn IS A LIST, MATCH IN THERE TOO
//BUT NOT FULLY RECURSIVEO JUST ONE LEVEL
BEGIN
TBD();
END;
EXPORT LNMRL(LST)
//EXT:NORMALISE COMPRESSES LST
//X:NOP
BEGIN
RETURN LST;
END;
EXPORT LSAME(LST1,LST2)
//EXT: IMPLEMENTS LMRL SAME
BEGIN
RETURN EQ(LST1,LST2);
END;
EXPORT ThatsAllFunctions()
BEGIN
END;
EXPORT LISTEXTRAS()
BEGIN
END;